Authentication

Name Done uses a two-tier authentication model: a long-lived API key exchanged for a short-lived JWT. This keeps your API key off the wire for every autocomplete request.

How It Works

1

Get an API key

Sign up at auth.namedone.com/signup and create an API key. It starts with nd_.

2

Exchange for a JWT

POST your API key to the token endpoint. You receive a JWT valid for 5 minutes.

3

Query autocomplete

Pass the JWT as a token query parameter on every autocomplete request. The SDK handles this automatically.

API Keys

Your API key is a long-lived secret that starts with nd_. It is 67 characters long and cryptographically random. Never expose it in client-side code or commit it to version control.

Important: Your API key is a secret. Anyone with your key can make requests on your behalf. Store it securely (e.g. in an environment variable) and never embed it in client-side JavaScript that users can inspect.

Token Endpoint

POSThttps://token.namedone.com/v1

Request

{
"apiKey": "nd_..."
}

Response (200)

{
"token": "eyJhbGciOiJIUzI1NiIs...",
"expiresIn": 300,
"tokenType": "Bearer"
}

Error Responses

StatusErrorDescription
400Invalid JSON bodyRequest body is not valid JSON.
401Invalid API keyAPI key not found or prefix mismatch.
401API key has been revokedThe key was revoked in the portal.
402Insufficient creditsAccount has no remaining credits.
403Account suspendedAccount has been suspended.
405Method not allowedOnly POST is supported.

JWT Details

The JWT is signed with HMAC-SHA256 (HS256). It contains the following claims:

ClaimTypeDescription
substringAccount ID (e.g. acct_123)
jtistringUnique token ID (for session tracking)
kidstringSigning key ID (e.g. v1)
tvnumberToken version (for account-level revocation)
iatnumberIssued-at timestamp (Unix seconds)
expnumberExpiry timestamp (Unix seconds, 5 min after iat)

Using the SDK (Recommended)

The @namedone/autocomplete SDK handles token exchange, caching, and refresh automatically. Just pass your API key and the SDK does the rest.

Automatic token management
1import { createClient } from "@namedone/autocomplete"
2
3// The SDK creates a CachedTokenClient internally
4const nd = createClient("nd_...")
5
6// First call — fetches a JWT, then queries autocomplete
7const { results } = await nd.firstNames("jo")
8
9// Subsequent calls within 5 min — reuses cached JWT
10const { results } = await nd.lastNames("sm")
11
12// After 5 min — automatically refreshes the JWT
13const { results } = await nd.postcodes("SW1A")

The SDK prefetches the JWT on mount when you call prefetchToken(), so the first keystroke doesn't wait for a token round-trip.

Manual Token Management

For advanced use cases, you can manage tokens yourself using the @namedone/token package.

TokenClient
1import { TokenClient } from "@namedone/token"
2import { AutocompleteClient } from "@namedone/autocomplete"
3
4// Exchange API key for JWT
5const tokens = new TokenClient({ apiKey: "nd_..." })
6const { token } = await tokens.getToken()
7
8// Use the JWT directly
9const client = new AutocompleteClient({ token })
10const { results } = await client.firstNames("jo")

Or use CachedTokenClient for automatic caching and refresh:

CachedTokenClient
1import { CachedTokenClient } from "@namedone/token"
2import { AutocompleteClient } from "@namedone/autocomplete"
3
4const tokens = new CachedTokenClient({ apiKey: "nd_..." })
5
6// AutocompleteClient calls tokens.getToken() on each request
7const client = new AutocompleteClient({
8 tokenProvider: () => tokens.getToken().then(t => t.token),
9})
10
11const { results } = await client.firstNames("jo")

Direct API (curl)

If you're not using the SDK, you can exchange your API key and query the API directly:

1# 1. Exchange your API key for a JWT
2curl -X POST https://token.namedone.com/v1 \
3 -H "Content-Type: application/json" \
4 -d '{"apiKey":"nd_..."}'
5
6# Response:
7# {"token":"eyJ...","expiresIn":300,"tokenType":"Bearer"}
8
9# 2. Query autocomplete with the JWT
10curl "https://autocomplete.namedone.com/v1/first-name/jo?token=eyJ..."

Token as Query Parameter

The JWT is passed as a token query parameter (not an Authorization header). This avoids triggering CORS preflight (OPTIONS) requests — a GET with no custom headers is a "simple request" that browsers send without preflight. The CloudFront Function strips the token from the query string before it reaches the origin.

Token Caching

JWTs are valid for 5 minutes. The SDK's CachedTokenClient refreshes the token 30 seconds before expiry. Concurrent requests share a single in-flight refresh (deduplication), so you can safely call getToken() on every request.

// First call — hits the API
const t1 = await tokens.getToken()
// Second call — returns cached token (no network)
const t2 = await tokens.getToken()
// After 4.5 min — refreshes 30s before expiry
const t3 = await tokens.getToken()

Revocation

  • API key revocation: Revoking an API key in the portal immediately prevents new JWTs from being issued. Existing JWTs remain valid until they expire (up to 5 min).
  • Account suspension: Suspending an account prevents new JWTs from being issued. The token version (tv) claim invalidates all previously issued tokens when incremented.