API-dokumentation
Et offentligt REST-API til kontrakter, skabeloner, kunder, workspaces og brugere. Samme data som i appen — hentet med en nøgle, I selv styrer.
Kom i gang
Alle kald går til det samme grundlag og svarer med JSON. Send din nøgle som en Bearer-token i Authorization-headeren.
Grundadresse: https://contracts.todai.ai/api/public/v1
curl "https://contracts.todai.ai/api/public/v1/contracts?limit=5" \
-H "Authorization: Bearer tdk_din_nøgle"Alle endepunkter understøtter OPTIONS til CORS-preflight, som svarer 204 uden autentificering.
Nøgler og scopes
Nøgler oprettes i appen under Indstillinger → API-nøgler og begynder med tdk_. En nøgle kan aldrig se mere end den bruger, der oprettede den. Den kan begrænses til bestemte workspaces og få en udløbsdato, og du vælger selv hvilke scopes den har.
| Scope | Giver adgang til |
|---|---|
| contracts:read | Læs kontrakter og enkelt-kontrakt |
| contract_content:read | Læs kontraktens sektioner, parter og fulde tekst |
| signatures:read | Læs underskrivere og deres status |
| audit:read | Læs revisionsspor for en kontrakt |
| customers:read | Læs kunder |
| templates:read | Læs skabeloner og skabelonsektioner |
| workspaces:read | Læs workspaces og medlemmer |
| users:read | Læs brugere og roller |
| users:write | Opret eller opdater brugere på @todai.ai |
Kontrakter
Hent listen af kontrakter, en enkelt kontrakt med indhold, den fulde tekst eller hele revisionssporet.
Liste kontrakter
Returnerer kontrakter sorteret efter oprettelsestidspunkt, nyeste først.
Kræver scope contracts:read
| Parameter | Type | Bemærkning |
|---|---|---|
| limit | heltal | 1–200, standard 50 |
| search | tekst | Delvis match på titel, uden hensyn til store og små bogstaver |
| status | tekst | fx draft, sent, signed |
Svar: { contracts: ContractSummary[] }
curl "https://contracts.todai.ai/api/public/v1/contracts?status=signed&limit=20" \
-H "Authorization: Bearer tdk_…"Mulige fejl: 401, 403, 500
Hent én kontrakt
Svaret udvides efter nøglens øvrige scopes: signatures:read giver signers, og contract_content:read giver sections og parties.
Kræver scope contracts:read
Svar: { contract, signers?, parties?, sections? }
curl "https://contracts.todai.ai/api/public/v1/contracts/4f0c…" \
-H "Authorization: Bearer tdk_…"Mulige fejl: 401, 403, 404, 500
Hent kontraktens fulde tekst
Importerede PDF'er har typisk indholdet i text. Kontrakter bygget i Todai har også body_html.
Kræver scope contract_content:read
Svar: { id, title, text, chars, body_html }
curl "https://contracts.todai.ai/api/public/v1/contracts/4f0c…/text" \
-H "Authorization: Bearer tdk_…"Mulige fejl: 401, 403, 404
Revisionsspor for kontrakten
Op til 200 hændelser, nyeste først. API'et returnerer hele sporet — også hændelser der er skjult i brugerfladen.
Kræver scope audit:read
Svar: { events: AuditEvent[] }
curl "https://contracts.todai.ai/api/public/v1/contracts/4f0c…/audit" \
-H "Authorization: Bearer tdk_…"Mulige fejl: 401, 403, 404
Kunder
Kundekartoteket, inklusive HubSpot-id og seneste work order-nummer.
Liste kunder
Returnerer alle kunder som nøglen har adgang til.
Kræver scope customers:read
Svar: { customers: Customer[] }
curl "https://contracts.todai.ai/api/public/v1/customers" \
-H "Authorization: Bearer tdk_…"Mulige fejl: 401, 403, 500
Skabeloner
Skabelonbiblioteket og de sektioner en skabelon består af.
Liste skabeloner
Returnerer alle skabeloner som nøglen har adgang til.
Kræver scope templates:read
Svar: { templates: Template[] }
curl "https://contracts.todai.ai/api/public/v1/templates" \
-H "Authorization: Bearer tdk_…"Mulige fejl: 401, 403
Hent skabelon med sektioner
Skabelonen og dens sektioner i rækkefølge, med angivelse af hvilke der er med som standard.
Kræver scope templates:read
Svar: { template, sections: TemplateSection[] }
curl "https://contracts.todai.ai/api/public/v1/templates/9ab1…" \
-H "Authorization: Bearer tdk_…"Mulige fejl: 401, 403, 404
Workspaces
Workspaces og deres medlemmer med rolle og eneunderskriftsret.
Liste workspaces med medlemmer
Hvert workspace indeholder listen af medlemmer med rolle og can_sign_alone.
Kræver scope workspaces:read
Svar: { workspaces: Workspace[] }
curl "https://contracts.todai.ai/api/public/v1/workspaces" \
-H "Authorization: Bearer tdk_…"Mulige fejl: 401, 403
Brugere
Læs brugere og roller — og opret eller opdater brugere på jeres eget domæne.
Liste brugere med roller
Returnerer brugere med profil og tildelte roller (admin, editor, viewer).
Kræver scope users:read
Svar: { users: User[] }
curl "https://contracts.todai.ai/api/public/v1/users" \
-H "Authorization: Bearer tdk_…"Mulige fejl: 401, 403
Opret eller opdater en bruger
Findes brugeren ikke, oprettes den, og der sendes en invitationsmail (svar 201). Findes den i forvejen, opdateres profil og rolle uden ny mail (svar 200). Brugeren bliver ikke automatisk medlem af et workspace.
Kræver scope users:write
| Felt i body | Type | Bemærkning |
|---|---|---|
| tekst, påkrævet | Skal ende på @todai.ai, højst 255 tegn | |
| full_name | tekst | 1–200 tegn |
| phone | tekst | Højst 32 tegn, tal, mellemrum, +, () og - |
| avatar_url | tekst | Gyldig URL, højst 1000 tegn |
| role | admin | editor | viewer | Standard editor |
Svar: { id, email, role, created }
curl -X POST "https://contracts.todai.ai/api/public/v1/users" \
-H "Authorization: Bearer tdk_…" \
-H "Content-Type: application/json" \
-d '{"email":"ny@todai.ai","full_name":"Ny Kollega","role":"editor"}'Mulige fejl: 400, 401, 403, 500
Fejl
Fejl returneres altid som { "error": "…" }. Har nøglen ikke adgang til en bestemt kontrakt, svarer vi 404 frem for 403 — så en nøgle ikke kan bruges til at afsløre, at kontrakten findes.
| Kode | Betydning |
|---|---|
| 400 | Ugyldig JSON, eller validering af felterne fejlede. |
| 401 | Nøglen mangler, er ugyldig, udløbet eller tilbagekaldt. |
| 403 | Nøglen findes, men mangler det krævede scope. |
| 404 | Ressourcen findes ikke — eller er ikke tilgængelig for nøglen. |
| 500 | Serverfejl. Prøv igen, og kontakt os hvis den bliver ved. |
Datamodeller
Felterne herunder går igen på tværs af endepunkterne. Tidspunkter er ISO 8601 i UTC.
ContractSummary
| Felt | Type | Bemærkning |
|---|---|---|
| id | uuid | — |
| title | tekst | null | — |
| status | tekst | draft, sent, signed |
| type | tekst | null | — |
| language | tekst | null | — |
| direction | tekst | null | outgoing = I er leverandør, incoming = I er kunde |
| customer_name | tekst | null | — |
| hubspot_customer_id | tekst | null | — |
| work_order_number | tekst | null | — |
| customer_initials | tekst | null | — |
| workspace_id | uuid | null | — |
| owner_id | uuid | null | — |
| valid_until | dato | null | — |
| sent_at | tidspunkt | null | — |
| signed_at | tidspunkt | null | — |
| created_at | tidspunkt | — |
| updated_at | tidspunkt | — |
Contract
| Felt | Type | Bemærkning |
|---|---|---|
| … | alle felter fra ContractSummary | — |
| hubspot_deal_id | tekst | null | — |
| hubspot_deal_name | tekst | null | — |
Signer
| Felt | Type | Bemærkning |
|---|---|---|
| id | uuid | — |
| kind | tekst | internal, customer, other |
| full_name | tekst | null | — |
| tekst | null | — | |
| title | tekst | null | Stilling |
| sort_order | heltal | — |
| signed_at | tidspunkt | null | — |
| rejected_at | tidspunkt | null | — |
| withdrawn_at | tidspunkt | null | — |
Party
| Felt | Type | Bemærkning |
|---|---|---|
| id | uuid | — |
| name | tekst | null | — |
| role | tekst | null | — |
| address | tekst | null | — |
| cvr | tekst | null | — |
| sort_order | heltal | — |
ContractSection
| Felt | Type | Bemærkning |
|---|---|---|
| id | uuid | — |
| title | tekst | null | — |
| body | HTML | null | — |
| sort_order | heltal | — |
| included | boolsk | — |
| parent_section_id | uuid | null | — |
AuditEvent
| Felt | Type | Bemærkning |
|---|---|---|
| id | uuid | — |
| action | tekst | fx sent_for_signature, viewed, signed |
| actor_name | tekst | null | — |
| actor_email | tekst | null | — |
| details | objekt | null | — |
| created_at | tidspunkt | — |
Customer
| Felt | Type | Bemærkning |
|---|---|---|
| id | uuid | — |
| hubspot_customer_id | tekst | null | — |
| customer_name | tekst | null | — |
| initials | tekst | null | — |
| domain | tekst | null | — |
| workspace_id | uuid | null | — |
| last_work_order_number | heltal | null | — |
| updated_at | tidspunkt | — |
Template
| Felt | Type | Bemærkning |
|---|---|---|
| id | uuid | — |
| name | tekst | — |
| description | tekst | null | — |
| language | tekst | null | — |
| type | tekst | null | — |
| generator | tekst | null | — |
| workspace_id | uuid | null | — |
| owner_id | uuid | null | — |
| created_at | tidspunkt | — |
| updated_at | tidspunkt | — |
TemplateSection
| Felt | Type | Bemærkning |
|---|---|---|
| id | uuid | — |
| title | tekst | null | — |
| body | HTML | null | — |
| sort_order | heltal | — |
| is_default_included | boolsk | — |
| parent_section_id | uuid | null | — |
Workspace
| Felt | Type | Bemærkning |
|---|---|---|
| id | uuid | — |
| name | tekst | — |
| slug | tekst | null | — |
| description | tekst | null | — |
| sort_order | heltal | null | — |
| created_at | tidspunkt | — |
| members | WorkspaceMember[] | — |
WorkspaceMember
| Felt | Type | Bemærkning |
|---|---|---|
| workspace_id | uuid | — |
| user_id | uuid | — |
| role | tekst | null | — |
| can_sign_alone | boolsk | — |
User
| Felt | Type | Bemærkning |
|---|---|---|
| id | uuid | — |
| tekst | null | — | |
| full_name | tekst | null | — |
| avatar_url | tekst | null | — |
| phone | tekst | null | — |
| roles | liste af admin | editor | viewer | — |