DoDomain

OpenAPI spec

The machine-readable OpenAPI 3.1 description of the /api/v1 surface, generated from the same schemas the API validates with.

The whole /api/v1 surface is published as an OpenAPI 3.1 document:

https://dodomain.io/docs/openapi.json

It describes every endpoint on the REST API page: request and response bodies, query parameters, both authentication schemes and their OAuth scopes, and the exact error codes each endpoint can answer with, including the 429 Retry-After contract.

It is generated, not written

The document is produced from the same zod schemas the request handlers validate with. A CI gate regenerates it on every pull request and fails the build if it differs by a single byte from the committed file, and a second gate fails if any endpoint exists in the code without an entry in the spec. So the spec cannot quietly fall behind the API: either it is current, or the build is red.

Two consequences worth knowing:

  • Response objects do not set additionalProperties: false. We add response fields additively: records and warnings on the create-session response both arrived that way, so a client that rejected unknown keys would break on a release that broke nothing else. Ignore fields you do not recognise.
  • The version is v1, not a semver. The surface is versioned by its /api/v1 path prefix.

Using it

curl -sSL https://dodomain.io/docs/openapi.json -o dodomain-openapi.json

Point any OpenAPI-aware tool at that file or URL: an API client (Postman, Insomnia, Bruno, Hoppscotch), a client generator (openapi-generator, openapi-typescript, Kiota, Speakeasy), a mock server, or a contract-test runner.

AI assistants can call the API directly

If you want an assistant to use DoDomain rather than write code against it, connect the MCP server instead (see Connecting AI assistants). It runs on the same authentication, scopes and rate limits described here.

Authentication in the spec

Two security schemes are declared, and integrator endpoints accept either:

SchemeHow it appearsNotes
secretKeyAuthorization: Bearer dd_sk_...App-scoped, no scope grammar, server-to-server only.
oauth2Authorization-code flow with PKCETeam-scoped. Each operation lists the scope it needs; a missing scope answers 403 with details.code: SCOPE_MISSING.

Session-scoped endpoints (/api/v1/sessions/{token}/detect, /verify, and the one-click entry points) carry security: []: that is not an oversight. The unguessable session token in the path is the credential, which is what lets the hosted flow and the embeddable widget call them from a browser. Treat that token like a bearer token.

Two classes deviate from "either credential", and the spec says so per operation rather than in prose:

  • Credential-management operations take the secret key only. POST /api/v1/keys/rotate and every /api/v1/webhook-endpoints operation declare secretKey as their sole security requirement. An OAuth access token is refused with 403 and details.code: SECRET_KEY_REQUIRED: signing secrets and key rotation stay with the app's own credential rather than with a delegated consent grant.
  • GET /api/v1/sessions/{token} accepts either, or neither. It is one path with two arms, told apart by the shape of the path segment: pass a dd_sess_... token and send no Authorization header, or pass the session id and authenticate. The spec encodes that as an optional security requirement (a leading {} alongside the two credential entries) and the 200 as a oneOf over the two response shapes, because the two arms genuinely return different objects.

On this page

We use analytics cookies to understand how DoDomain is used. The sign-in cookie is essential and is set regardless; the privacy policy names every service involved. Privacy policy