API Tokens
API tokens authenticate your widget embed requests to the DoesItHaveIt? API. Every widget deployment uses a token, and tokens are tied to your Premium Plus account's credit pool.
Generating a token
- Go to Dashboard → Widget → Tokens
- Click Generate token
- Enter a descriptive name for the token (e.g.,
Production - myrealty.com,Staging - test.myrealty.com) - Add allowed domains — one per line (e.g.,
www.myrealty.com,listings.myrealty.com) - Click Generate
- Copy the token immediately — it is displayed in full only once
After you close the generation dialog, you can no longer view the full token value. You can see the token name, its last 4 characters, creation date, last used date, and domain restrictions — but not the full secret. If you lose the token, revoke it and generate a new one.
Token format
Tokens are 48-character hex strings prefixed with dihi_:
dihi_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6
Token permissions
All widget API tokens are read-only by design — they can only fetch address data for the widget. Tokens cannot write to your account, change your subscription, purchase credits, or access your billing information. There is no write-access token type.
Tokens are scoped to:
- Address lookups for the widget display
- The data categories your Premium Plus plan includes
- Requests from your allowed domains only
Domain restrictions
Domain restrictions are the primary security control for tokens. When a page loads the widget and makes an API call, the request includes an Origin header identifying the caller's domain. The DoesItHaveIt? API checks this against your token's allowed domain list and rejects the request if the domain isn't listed.
Adding domains:
- Dashboard → Widget → Tokens → [token name] → Edit
- Add the domain (e.g.,
myrealty.com) — do not includehttps://or paths - Save
Wildcard support:
| Pattern | Matches |
|---|---|
myrealty.com | Only myrealty.com exactly |
www.myrealty.com | Only www.myrealty.com |
*.myrealty.com | All subdomains: listings.myrealty.com, app.myrealty.com, etc. |
localhost | Local development (localhost at any port) |
Revoking tokens
To immediately invalidate a token:
- Dashboard → Widget → Tokens → [token name] → Revoke
- Confirm the revocation
Revoked tokens are rejected by the API immediately. Any pages using the revoked token will show the "service unavailable" message until a new token is embedded. There is no grace period.
Revoke tokens if:
- You suspect the token has been publicly exposed (e.g., accidentally committed to a public Git repo)
- You're decommissioning a site or integration
- You're rotating tokens as part of a regular security practice
Rotating tokens
Token rotation is the practice of periodically replacing an active token with a new one to limit the window of exposure if a token is ever compromised. To rotate:
- Generate a new token with the same domain restrictions
- Deploy the new token to your site (update the
data-tokenattribute in your embed snippet) - Verify the new token is working in production (check Dashboard → Widget Credits for new activity)
- Revoke the old token
Rotate tokens if you suspect compromise, or periodically (every 6–12 months) as a best practice.
Security best practices
Never expose your API token in a public location:
- Do not commit the token to a public GitHub repository
- Do not include the token in a public-facing JavaScript bundle where it can be easily extracted by a user inspecting source code
While tokens are domain-restricted and the damage from exposure is limited (an attacker can only consume your widget credits, not access sensitive data), domain restrictions can be bypassed by a sophisticated attacker who spoofs the Origin header on server-side requests. Keeping the token private is still the best practice.
For server-side rendered sites (Next.js, Rails, Django, etc.), inject the token as a server-side environment variable rather than hardcoding it in your template:
<!-- Good: token from environment variable at render time -->
<script
src="https://doesithaveit.com/embed/v1/widget.js"
data-token="{{ process.env.DIHI_TOKEN }}"
async
></script>
For static sites where you cannot inject environment variables, the domain restriction is your primary defense — ensure your allowed domains list is tight and does not use overly broad wildcards.
Managing multiple tokens
You can create multiple tokens — for example, one per domain, one per environment (dev/staging/production), or one per team that manages different integrations. Each token has its own name, domain restriction, and activity log. All tokens draw from the same widget credit pool.
To see all tokens: Dashboard → Widget → Tokens. The list shows token name, last 4 characters, creation date, last used timestamp, and request count.