API reference
Current release · Updated October 2, 2026
Base URL and scope
Use https://app.drykraft.com/api. This reference covers the current implemented API, including application routes and public provider callbacks. It is not a promise that the full PRD is implemented. API keys, service accounts, Bearer authentication and an external SDK are not available. OpenAPI is downloadable for inspection and tooling; use session authentication for protected routes.
Authenticate and select a workspace
POST /api/auth/login with email/password or use signup, then retain the HTTP-only drykraft_session cookie. Production uses Secure, SameSite=Lax and a seven-day lifetime. Browser clients should make same-origin requests with credentials included. State-changing Origin headers must match the request host; cross-origin browser integration is not enabled.
Read /api/session to get accessible workspace IDs and current role. Use /api/session/workspace to select a member workspace. X-Workspace-ID can select another workspace you belong to per request, but cannot bypass membership or workspace hostname checks. A tenant_id in a request body does not grant access. Account-security endpoints require an account session even before onboarding; most other protected endpoints require a selected workspace.
Roles, billing and state
Workspace member means owner/admin/member/viewer can read. Owner, admin or member can change business data; viewer is read-only. Configuration/launch generally needs owner/admin. Only owner manages billing and administrators. Endpoint descriptions name finer constraints. Most writes need active trial/paid access; account security, billing and access removal remain available after expiry.
For versioned records, smart lists, dashboards and member changes, read the latest version and submit it. A 409 must trigger a refresh and review. Record PUT replaces complete data; bulk update merges specified fields. Financial records must use Finance, not generic record writes. Launched outreach/immutable workflow versions cannot be rewritten.
Pagination and request limits
Use next_cursor as an opaque token and keep search/filter settings unchanged while paging. Records default to 50 rows, max 100; team/session pages use 25. Some history endpoints intentionally return only a recent bounded list and have no next page. Returned metadata can include additional row fields; do not depend on fields outside documented contracts.
JSON request bodies are capped at 512 KB. General /api limit is 300 requests/minute per client/process; auth and generic hooks have 30/15 minutes; raw Dodo/Meta hooks have 120/minute. Account password changes additionally allow ten per account/15 minutes. Limits use response RateLimit headers where present. Retry after the indicated window. Provider/connection sending limits are separate. A 413 may be the parser’s non-JSON error response; clients should handle non-JSON failures.
Errors and safe retry
Normal errors are {error:{message,request_id}} with X-Request-ID; limiter responses may omit the ID, and parser/provider ingress errors can differ. 400 input validation, 401 sign-in/signature, 402 subscription, 403 permission, 404 resource, 409 conflict, 410 invitation expiry, 413 body size, 429 rate limit and 5xx server/provider failure. Preserve the request ID when requesting support.
Use a stable UUID for CSV commit/payment entry retries with identical content. Generic workflow hooks accept Idempotency-Key. Other creates/launches do not have a universal idempotency key. A network failure is not proof of failure: refresh state before retrying payment checkout, outreach launch or external execution. Unknown outreach results require provider inspection; do not blindly resend.
curl --request POST \
--url 'https://app.drykraft.com/api/auth/login' \
--cookie-jar ./drykraft-session.txt \
--header 'Content-Type: application/json' \
--data '{"email":"you@example.com","password":"<YOUR_PASSWORD>"}'
curl --url 'https://app.drykraft.com/api/session' \
--cookie ./drykraft-session.txtThe example uses your private account only. Keep the local cookie file private and delete it when done. Never paste credentials into shared docs, logs or screenshots. Replace angle-bracket placeholders before running examples.
