Skip to main content

The key

A Developer API key reaches the whole tenant’s data within its scopes and its owner’s permissions. Treat it as a service password.
  • Keep it in a secret manager or an environment variable, not in the repository and not in a config file next to the code.
  • Never use it in a frontend or mobile app, where every user can read it.
  • Issue a separate key per integration. A compromise then costs you one key rather than all access.
  • Rotation is manual: create a new key, switch the integration over, then revoke the old one. Keys currently have no expiry.
  • The secret is shown once at creation. Lists show only the 12-character prefix.
Never log the key value or paste it into examples that end up in an issue tracker or a chat. If a key may have leaked, revoke it in settings; revocation takes effect immediately.

What a key can see

Effective access is the intersection of two limits:
  1. The key’s scopes. An endpoint requires a specific scope; without it the request is rejected with DEVELOPER.SCOPE_INSUFFICIENT.
  2. The owner’s permissions. The key sees exactly the employees, documents, and fields available to the permission profile of the user who created it. Permissions are evaluated per request: narrow the owner’s access and the key narrows with it.
Two consequences follow. Sensitive fields the owner may not see are omitted from the response, and their names are listed in redacted_fields. A single resource you cannot access is indistinguishable from one that does not exist: both return 404. A key stops working once its owner is removed from the tenant or deactivated, so a departure does not require a separate revocation — though reviewing the key list after one is still worthwhile.

Webhook URLs

Doodocs calls your server, so a subscription URL must satisfy two requirements:
  • the https scheme only;
  • a publicly resolvable address only: localhost, private ranges, and cloud metadata addresses are rejected with DEVELOPER.WEBHOOK_URL_INVALID.
For local debugging, expose a tunnel with a public https address.

Verifying deliveries

Every delivery is signed: the Doodocs-Signature header carries a timestamp and an HMAC-SHA256 of {t}.{body} computed with the subscription secret. Verify the signature before parsing the body and reject requests older than five minutes, or an intercepted delivery can be replayed. The secret is shown once when the subscription is created and is not rotated. To replace it, create a new subscription with the same URL and event types, switch your verification to the new secret, and delete the old one. Event payloads are deliberately thin: type, time, and a resource id. Personal data never leaves for an external URL — you fetch it with your own key, where scopes and field redaction apply.
Document events are delivered for every document in the tenant the endpoint subscribes to, regardless of the key owner’s per-document permissions. The event itself carries only an id and a timestamp; the document’s content stays gated by permissions when you read it through GET /documents/{id}.