DraftFilterDeveloper API

Developer reference

Authentication

Every /v1/* route accepts three credential types through one policy: customer API keys, Firebase ID tokens for signed-in web users, and Firebase App Check tokens for anonymous browser scans.

API keys use one of these headers:

text
Authorization: Bearer df_live_key_...
X-Api-Key: df_live_key_...

Prefer Authorization: Bearer for new clients. X-Api-Key exists for environments where setting the authorization header is inconvenient.

Signed-in web users send a Firebase ID token as the bearer credential:

text
Authorization: Bearer <firebase-id-token>

Anonymous browser scans send a Firebase App Check token instead:

text
X-Firebase-AppCheck: <app-check-token>

Credentials are resolved fail-closed. When an Authorization header is present it must be valid on its own; an invalid bearer credential is never downgraded to the App Check path even if an X-Firebase-AppCheck header is also sent. An invalid Firebase ID token or App Check token returns 401 invalid_public_credential.

json
{
  "error": {
    "code": "invalid_public_credential",
    "message": "Missing or invalid public credential."
  }
}

API keys and signed-in Firebase users hold all public scopes:

text
score_jobs:create
score_jobs:read
rewrite_jobs:create
rewrite_jobs:read
uploads:create

Anonymous App Check credentials are scoring only: they hold just score_jobs:create and score_jobs:read. A /v1/rewrite-jobs or /v1/uploads request with only an App Check token returns 403 insufficient_scope.

Missing, unknown, expired, revoked, or rotated-away API keys return 401 invalid_api_key. A valid key without the required scope returns 403 insufficient_scope.

json
{
  "error": {
    "code": "invalid_api_key",
    "message": "The API key is missing or invalid."
  }
}

Jobs are owned by the credential that created them: an API key sees only its own jobs, a signed-in user sees the jobs created with their ID token, and an anonymous browser can poll only the jobs created with the same App Check app and network origin. Anonymous and free-account scans are subject to the allowances described in rate limits.

Dashboard authentication is separate. /dashboard/* routes use Firebase ID tokens for the web app, not customer API keys, and are unsupported internal implementation details for public API clients.