{"openapi":"3.0.3","info":{"title":"Handee HQ API","version":"1.0","description":"Read and write the CRM from other systems. Lists page with nextCursor; writes accept an Idempotency-Key header."},"servers":[{"url":"https://crm.handee.co.za/api/v1"}],"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"An API key from Settings → API, sent as Authorization: Bearer sl_…"}},"schemas":{},"parameters":{}},"paths":{"/health":{"get":{"summary":"Liveness and version","description":"No credentials needed.","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"version":{"type":"string"}},"required":["ok","version"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}}},"/me":{"get":{"summary":"Who this key or session is","description":"Needs a key with read scope.","security":[{"apiKey":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"kind":{"type":"string","enum":["key","user"]},"name":{"type":"string"},"scope":{"type":"string","enum":["read","write"]}},"required":["kind","name","scope"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}}},"/search":{"get":{"summary":"Find companies or people by name, email, domain or job title","description":"Needs a key with read scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"q","in":"query"},{"schema":{"type":"string","enum":["company","contact","any"],"default":"any"},"required":false,"name":"kind","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"total":{"type":"integer"},"rows":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["company","contact"]},"id":{"type":"string"},"name":{"type":"string"},"detail":{"type":"string","description":"Wording for people: 'Active client' or the relationship, and the sector; or the job title and company"},"href":{"type":"string"},"relationship":{"type":"string","description":"Companies: the stored relationship"},"activeClient":{"type":"boolean","description":"Companies: on the Active clients list"}},"required":["kind","id","name","detail","href"]}}},"required":["total","rows"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}}},"/companies":{"get":{"summary":"List companies","description":"Needs a key with read scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"description":"The nextCursor from the previous page"},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50,"description":"Rows per page, 1 to 100"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"description":"Free-text search"},"required":false,"name":"q","in":"query"},{"schema":{"type":"string","enum":["client","prospect","partner","competitor"],"description":"client | prospect | partner | competitor"},"required":false,"name":"relationship","in":"query"},{"schema":{"type":"string","minLength":1},"required":false,"name":"sector","in":"query"},{"schema":{"type":"boolean","description":"true = only companies in Active clients"},"required":false,"name":"activeClient","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"relationship":{"type":"string"},"sector":{"type":"string","nullable":true},"industry":{"type":"string","nullable":true},"website":{"type":"string","nullable":true},"domains":{"type":"array","items":{"type":"string"}},"activeClientSince":{"type":"string","nullable":true},"contacts":{"type":"integer"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"href":{"type":"string"}},"required":["id","name","relationship","sector","industry","website","domains","activeClientSince","contacts","createdAt","updatedAt","href"]}},"nextCursor":{"type":"string","nullable":true},"total":{"type":"integer","description":"Rows matching the filters, across all pages"}},"required":["items","nextCursor","total"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"summary":"Create a company","description":"Needs a key with write scope.","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"relationship":{"type":"string","enum":["Prospect","Client","Partner / Supplier","Competitor"],"default":"Prospect"},"sector":{"type":"string","nullable":true,"maxLength":100},"industry":{"type":"string","nullable":true,"maxLength":100},"website":{"type":"string","nullable":true,"maxLength":300},"domains":{"type":"array","items":{"type":"string","minLength":1,"maxLength":200},"maxItems":20,"description":"Email domains, e.g. acme.co.za"},"headOffice":{"type":"string","nullable":true,"maxLength":200},"whatTheyDo":{"type":"string","nullable":true,"maxLength":2000},"notes":{"type":"string","nullable":true,"maxLength":2000}},"required":["name"],"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"relationship":{"type":"string"},"sector":{"type":"string","nullable":true},"industry":{"type":"string","nullable":true},"website":{"type":"string","nullable":true},"domains":{"type":"array","items":{"type":"string"}},"activeClientSince":{"type":"string","nullable":true},"contacts":{"type":"integer"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"href":{"type":"string"}},"required":["id","name","relationship","sector","industry","website","domains","activeClientSince","contacts","createdAt","updatedAt","href"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}}},"/companies/{id}":{"get":{"summary":"One company in full: team, contracts, deals, recent activity","description":"Needs a key with read scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"relationship":{"type":"string","description":"The stored value: Prospect, Client, Partner / Supplier, Competitor"},"activeClientSince":{"type":"string","nullable":true},"sector":{"type":"string","nullable":true},"industry":{"type":"string","nullable":true},"website":{"type":"string","nullable":true},"headOffice":{"type":"string","nullable":true},"legalName":{"type":"string","nullable":true},"accountPlanNotes":{"type":"string","nullable":true},"href":{"type":"string"},"hrefs":{"type":"object","additionalProperties":{"type":"string"}},"contactCount":{"type":"integer"},"team":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"fullName":{"type":"string"},"jobTitle":{"type":"string","nullable":true},"role":{"type":"string","description":"Wording for people, e.g. \"Sponsor\"; PATCH takes clientRole"},"clientRole":{"type":"string","enum":["sponsor","day_to_day","billing","procurement","technical","other"]},"email":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"href":{"type":"string"}},"required":["id","fullName","jobTitle","role","clientRole","email","phone","href"]}},"otherPeople":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"fullName":{"type":"string"},"jobTitle":{"type":"string","nullable":true},"href":{"type":"string"}},"required":["id","fullName","jobTitle","href"]}},"contracts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"company":{"type":"string"},"status":{"type":"string","description":"Wording for people, e.g. \"Active\"; PATCH takes statusValue"},"statusValue":{"type":"string","enum":["proposed","active","paused","ended","declined"]},"billing":{"type":"string","description":"Wording for people, e.g. \"Ad hoc job\"; PATCH takes billingValue"},"billingValue":{"type":"string","enum":["retainer","once_off"]},"monthlyZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"totalZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"termMonths":{"type":"integer","nullable":true},"startAt":{"type":"string","nullable":true,"description":"YYYY-MM-DD"},"endAt":{"type":"string","nullable":true,"description":"YYYY-MM-DD"},"accountManager":{"type":"string","nullable":true},"href":{"type":"string"}},"required":["id","name","status","statusValue","billing","billingValue","monthlyZar","totalZar","termMonths","startAt","endAt","accountManager","href"]}},"openDeals":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"company":{"type":"string"},"companyId":{"type":"string"},"status":{"type":"string","description":"Wording for people, e.g. \"Proposal sent\"; PATCH takes statusValue"},"statusValue":{"type":"string","enum":["working","proposal_sent","onboarding","won","on_hold","lost"]},"dealType":{"type":"string","description":"Wording for people, e.g. \"Ad hoc job\"; PATCH takes dealTypeValue"},"dealTypeValue":{"type":"string","enum":["retainer","once_off","both"]},"valueZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"monthlyZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"termMonths":{"type":"integer","nullable":true},"onceOffZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"probabilityPct":{"type":"integer"},"anticipatedStart":{"type":"string","nullable":true},"closedAt":{"type":"string","nullable":true},"accountManager":{"type":"string","nullable":true},"primaryContact":{"type":"string","nullable":true},"href":{"type":"string"}},"required":["id","name","company","companyId","status","statusValue","dealType","dealTypeValue","valueZar","monthlyZar","termMonths","onceOffZar","probabilityPct","anticipatedStart","closedAt","accountManager","primaryContact","href"]}},"wonDeals":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"href":{"type":"string"}},"required":["id","name","href"]}},"recentActivity":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","nullable":true},"type":{"type":"string"},"subject":{"type":"string","nullable":true},"with":{"type":"string","nullable":true}},"required":["date","type","subject","with"]}}},"required":["id","name","relationship","activeClientSince","sector","industry","website","headOffice","legalName","accountPlanNotes","href","hrefs","contactCount","team","otherPeople","contracts","openDeals","wonDeals","recentActivity"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}}},"/contacts":{"get":{"summary":"List contacts","description":"Needs a key with read scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"description":"The nextCursor from the previous page"},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50,"description":"Rows per page, 1 to 100"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"description":"Free-text search"},"required":false,"name":"q","in":"query"},{"schema":{"type":"string","minLength":1},"required":false,"name":"companyId","in":"query"},{"schema":{"type":"string","enum":["sponsor","day_to_day","billing","procurement","technical","other"]},"required":false,"name":"clientRole","in":"query"},{"schema":{"type":"string","enum":["not_contacted","contacted","replied","meeting_booked","not_interested","do_not_contact"]},"required":false,"name":"outreachStatus","in":"query"},{"schema":{"type":"boolean","description":"true = executives, managers and researched decision-makers only"},"required":false,"name":"decisionMakers","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"fullName":{"type":"string"},"firstName":{"type":"string","nullable":true},"surname":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"jobTitle":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"linkedinUrl":{"type":"string","nullable":true},"clientRole":{"type":"string","nullable":true},"outreachStatus":{"type":"string"},"nextActionAt":{"type":"string","nullable":true},"lastContactedAt":{"type":"string","nullable":true},"tags":{"type":"array","items":{"type":"string"}},"company":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"href":{"type":"string"}},"required":["id","fullName","firstName","surname","email","jobTitle","phone","linkedinUrl","clientRole","outreachStatus","nextActionAt","lastContactedAt","tags","company","createdAt","updatedAt","href"]}},"nextCursor":{"type":"string","nullable":true},"total":{"type":"integer","description":"Rows matching the filters, across all pages"}},"required":["items","nextCursor","total"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"summary":"Create a contact (returns the existing one if the email is already known)","description":"Needs a key with write scope.","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"companyId":{"type":"string","minLength":1,"description":"Company the person belongs to"},"fullName":{"type":"string","minLength":1,"maxLength":200},"firstName":{"type":"string","nullable":true,"maxLength":100},"surname":{"type":"string","nullable":true,"maxLength":100},"email":{"type":"string","nullable":true,"format":"email"},"jobTitle":{"type":"string","nullable":true,"maxLength":200},"phone":{"type":"string","nullable":true,"maxLength":100},"linkedinUrl":{"type":"string","nullable":true,"format":"uri"},"clientRole":{"type":"string","nullable":true,"enum":["sponsor","day_to_day","billing","procurement","technical","other"]},"outreachStatus":{"type":"string","enum":["not_contacted","contacted","replied","meeting_booked","not_interested","do_not_contact"]},"notes":{"type":"string","nullable":true,"maxLength":2000,"description":"CRM notes"},"tags":{"type":"array","items":{"type":"string","minLength":1,"maxLength":40},"maxItems":20,"description":"The lists the person is on (an imported sheet's tag, say); on PATCH the list replaces the one on file, so send the tags to keep too"}},"required":["companyId","fullName"],"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"fullName":{"type":"string"},"firstName":{"type":"string","nullable":true},"surname":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"jobTitle":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"linkedinUrl":{"type":"string","nullable":true},"clientRole":{"type":"string","nullable":true},"outreachStatus":{"type":"string"},"nextActionAt":{"type":"string","nullable":true},"lastContactedAt":{"type":"string","nullable":true},"tags":{"type":"array","items":{"type":"string"}},"company":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"href":{"type":"string"}},"required":["id","fullName","firstName","surname","email","jobTitle","phone","linkedinUrl","clientRole","outreachStatus","nextActionAt","lastContactedAt","tags","company","createdAt","updatedAt","href"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}}},"/contacts/{id}":{"get":{"summary":"One contact in full","description":"Needs a key with read scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"fullName":{"type":"string"},"jobTitle":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"roleClass":{"type":"string","nullable":true},"clientRole":{"type":"string","nullable":true,"description":"Wording for people, e.g. \"Sponsor\"; PATCH takes clientRoleValue"},"clientRoleValue":{"type":"string","nullable":true,"enum":["sponsor","day_to_day","billing","procurement","technical","other"]},"outreachStatus":{"type":"string","description":"Wording for people, e.g. \"Not contacted\"; PATCH takes outreachStatusValue"},"outreachStatusValue":{"type":"string","enum":["not_contacted","contacted","replied","meeting_booked","not_interested","do_not_contact"]},"lastContactedAt":{"type":"string","nullable":true},"nextActionAt":{"type":"string","nullable":true},"nextActionNote":{"type":"string","nullable":true},"linkedinUrl":{"type":"string","nullable":true},"bio":{"type":"string","nullable":true},"company":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"relationship":{"type":"string"},"href":{"type":"string"}},"required":["id","name","relationship","href"]},"recentActivity":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","nullable":true},"type":{"type":"string"},"subject":{"type":"string","nullable":true}},"required":["date","type","subject"]}},"href":{"type":"string"}},"required":["id","fullName","jobTitle","email","phone","roleClass","clientRole","clientRoleValue","outreachStatus","outreachStatusValue","lastContactedAt","nextActionAt","nextActionNote","linkedinUrl","bio","company","recentActivity","href"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}},"patch":{"summary":"Update fields on a contact","description":"Needs a key with write scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"companyId":{"type":"string","minLength":1,"description":"Company the person belongs to"},"fullName":{"type":"string","minLength":1,"maxLength":200},"firstName":{"type":"string","nullable":true,"maxLength":100},"surname":{"type":"string","nullable":true,"maxLength":100},"email":{"type":"string","nullable":true,"format":"email"},"jobTitle":{"type":"string","nullable":true,"maxLength":200},"phone":{"type":"string","nullable":true,"maxLength":100},"linkedinUrl":{"type":"string","nullable":true,"format":"uri"},"clientRole":{"type":"string","nullable":true,"enum":["sponsor","day_to_day","billing","procurement","technical","other"]},"outreachStatus":{"type":"string","enum":["not_contacted","contacted","replied","meeting_booked","not_interested","do_not_contact"]},"notes":{"type":"string","nullable":true,"maxLength":2000,"description":"CRM notes"},"tags":{"type":"array","items":{"type":"string","minLength":1,"maxLength":40},"maxItems":20,"description":"The lists the person is on (an imported sheet's tag, say); on PATCH the list replaces the one on file, so send the tags to keep too"}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"fullName":{"type":"string"},"firstName":{"type":"string","nullable":true},"surname":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"jobTitle":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"linkedinUrl":{"type":"string","nullable":true},"clientRole":{"type":"string","nullable":true},"outreachStatus":{"type":"string"},"nextActionAt":{"type":"string","nullable":true},"lastContactedAt":{"type":"string","nullable":true},"tags":{"type":"array","items":{"type":"string"}},"company":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"href":{"type":"string"}},"required":["id","fullName","firstName","surname","email","jobTitle","phone","linkedinUrl","clientRole","outreachStatus","nextActionAt","lastContactedAt","tags","company","createdAt","updatedAt","href"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}}},"/contacts/{id}/outreach":{"post":{"summary":"Set a contact's outreach status","description":"Needs a key with write scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["not_contacted","contacted","replied","meeting_booked","not_interested","do_not_contact"]},"note":{"type":"string","nullable":true,"maxLength":2000},"nextActionAt":{"type":"string","nullable":true,"pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-01-31"}},"required":["status"],"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"fullName":{"type":"string"},"firstName":{"type":"string","nullable":true},"surname":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"jobTitle":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"linkedinUrl":{"type":"string","nullable":true},"clientRole":{"type":"string","nullable":true},"outreachStatus":{"type":"string"},"nextActionAt":{"type":"string","nullable":true},"lastContactedAt":{"type":"string","nullable":true},"tags":{"type":"array","items":{"type":"string"}},"company":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"href":{"type":"string"}},"required":["id","fullName","firstName","surname","email","jobTitle","phone","linkedinUrl","clientRole","outreachStatus","nextActionAt","lastContactedAt","tags","company","createdAt","updatedAt","href"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}}},"/opportunities":{"get":{"summary":"List opportunities (deals)","description":"Needs a key with read scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"description":"The nextCursor from the previous page"},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50,"description":"Rows per page, 1 to 100"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"description":"Free-text search"},"required":false,"name":"q","in":"query"},{"schema":{"type":"string","minLength":1},"required":false,"name":"companyId","in":"query"},{"schema":{"type":"string","enum":["open","active","working","proposal_sent","onboarding","won","lost","on_hold"],"description":"open = working, proposal_sent or on_hold; won = won and onboarding; onboarding = won deals still being set up and contracted"},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","minLength":1},"required":false,"name":"accountManager","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-01-31"},"required":false,"name":"closedFrom","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-01-31"},"required":false,"name":"closedTo","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"},"dealType":{"type":"string"},"monthlyZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"termMonths":{"type":"integer","nullable":true},"onceOffZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"totalZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"probability":{"type":"integer"},"accountManager":{"type":"string","nullable":true},"startAt":{"type":"string","nullable":true},"closedAt":{"type":"string","nullable":true},"company":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"href":{"type":"string"}},"required":["id","name","status","dealType","monthlyZar","termMonths","onceOffZar","totalZar","probability","accountManager","startAt","closedAt","company","createdAt","updatedAt","href"]}},"nextCursor":{"type":"string","nullable":true},"total":{"type":"integer","description":"Rows matching the filters, across all pages"}},"required":["items","nextCursor","total"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"summary":"Create an opportunity (deal)","description":"Needs a key with write scope.","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"companyId":{"type":"string","minLength":1},"name":{"type":"string","minLength":1,"maxLength":200},"dealType":{"type":"string","enum":["retainer","once_off","both"],"default":"once_off","description":"retainer (monthly × term), once_off, or both"},"monthlyZar":{"type":"integer","nullable":true,"minimum":0,"maximum":1000000000},"termMonths":{"type":"integer","nullable":true,"minimum":1,"maximum":120},"onceOffZar":{"type":"integer","nullable":true,"minimum":0,"maximum":1000000000},"probability":{"type":"integer","minimum":0,"maximum":100,"description":"25, 50, 75 or 100, as in Handee HQ; another number is taken to the nearest of those"},"accountManager":{"type":"string","nullable":true,"maxLength":100},"startAt":{"type":"string","nullable":true,"pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Anticipated start","example":"2026-01-31"},"description":{"type":"string","nullable":true,"maxLength":2000},"primaryContactId":{"type":"string","nullable":true,"minLength":1},"status":{"type":"string","enum":["working","proposal_sent","onboarding","won","on_hold","lost"],"description":"working (default) | proposal_sent | onboarding (won, client being set up and contracted; becomes a client and its contract is created) | won (closed out; set on its own once onboarding is done) | on_hold | lost"}},"required":["companyId","name"],"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"},"dealType":{"type":"string"},"monthlyZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"termMonths":{"type":"integer","nullable":true},"onceOffZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"totalZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"probability":{"type":"integer"},"accountManager":{"type":"string","nullable":true},"startAt":{"type":"string","nullable":true},"closedAt":{"type":"string","nullable":true},"company":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"href":{"type":"string"}},"required":["id","name","status","dealType","monthlyZar","termMonths","onceOffZar","totalZar","probability","accountManager","startAt","closedAt","company","createdAt","updatedAt","href"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}}},"/opportunities/{id}":{"get":{"summary":"One deal with its contact, contracts and documents","description":"Needs a key with read scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}},"patch":{"summary":"Update a deal: value, dates, status (onboarding/won/lost/on_hold), description","description":"Needs a key with write scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"dealType":{"type":"string","enum":["retainer","once_off","both"],"default":"once_off","description":"retainer (monthly × term), once_off, or both"},"monthlyZar":{"type":"integer","nullable":true,"minimum":0,"maximum":1000000000},"termMonths":{"type":"integer","nullable":true,"minimum":1,"maximum":120},"onceOffZar":{"type":"integer","nullable":true,"minimum":0,"maximum":1000000000},"probability":{"type":"integer","minimum":0,"maximum":100,"description":"25, 50, 75 or 100, as in Handee HQ; another number is taken to the nearest of those"},"accountManager":{"type":"string","nullable":true,"maxLength":100},"startAt":{"type":"string","nullable":true,"pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Anticipated start","example":"2026-01-31"},"description":{"type":"string","nullable":true,"maxLength":2000},"primaryContactId":{"type":"string","nullable":true,"minLength":1},"status":{"type":"string","enum":["working","proposal_sent","onboarding","won","on_hold","lost"],"description":"working (default) | proposal_sent | onboarding (won, client being set up and contracted; becomes a client and its contract is created) | won (closed out; set on its own once onboarding is done) | on_hold | lost"},"lostReason":{"type":"string","nullable":true,"maxLength":2000}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"},"dealType":{"type":"string"},"monthlyZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"termMonths":{"type":"integer","nullable":true},"onceOffZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"totalZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"probability":{"type":"integer"},"accountManager":{"type":"string","nullable":true},"startAt":{"type":"string","nullable":true},"closedAt":{"type":"string","nullable":true},"company":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"href":{"type":"string"}},"required":["id","name","status","dealType","monthlyZar","termMonths","onceOffZar","totalZar","probability","accountManager","startAt","closedAt","company","createdAt","updatedAt","href"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}}},"/contracts":{"get":{"summary":"List contracts (retainers and ad hoc jobs)","description":"Needs a key with read scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"description":"The nextCursor from the previous page"},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50,"description":"Rows per page, 1 to 100"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"description":"Free-text search"},"required":false,"name":"q","in":"query"},{"schema":{"type":"string","minLength":1},"required":false,"name":"companyId","in":"query"},{"schema":{"type":"string","enum":["open","proposed","active","paused","ended","declined"],"description":"open = proposed, active or paused"},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","enum":["retainer","once_off"]},"required":false,"name":"billing","in":"query"},{"schema":{"type":"string","minLength":1},"required":false,"name":"accountManager","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-01-31"},"required":false,"name":"startsFrom","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-01-31"},"required":false,"name":"startsTo","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-01-31"},"required":false,"name":"endsFrom","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-01-31"},"required":false,"name":"endsTo","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"},"billing":{"type":"string"},"monthlyZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"termMonths":{"type":"integer","nullable":true},"totalZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"accountManager":{"type":"string","nullable":true},"startAt":{"type":"string"},"endAt":{"type":"string","nullable":true},"hourlyBillZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"hourlyCostZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"noProposal":{"type":"boolean"},"company":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"href":{"type":"string"}},"required":["id","name","status","billing","monthlyZar","termMonths","totalZar","accountManager","startAt","endAt","hourlyBillZar","hourlyCostZar","noProposal","company","createdAt","updatedAt","href"]}},"nextCursor":{"type":"string","nullable":true},"total":{"type":"integer","description":"Rows matching the filters, across all pages"}},"required":["items","nextCursor","total"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"summary":"Create a contract (retainer or ad hoc job) for a company; a proposed, active or paused one makes the company an active client (relationship Client), as in Handee HQ","description":"Needs a key with write scope.","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"companyId":{"type":"string","minLength":1},"name":{"type":"string","minLength":1,"maxLength":200},"billing":{"type":"string","enum":["retainer","once_off"],"default":"retainer","description":"retainer (monthly fee for a term) or once_off (ad hoc job)"},"startAt":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-01-31"},"endAt":{"type":"string","nullable":true,"pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Leave out for an open-ended retainer","example":"2026-01-31"},"monthlyZar":{"type":"integer","nullable":true,"minimum":0,"maximum":1000000000,"description":"Retainers: the monthly fee; the term value is monthly × months"},"valueZar":{"type":"integer","nullable":true,"minimum":0,"maximum":1000000000,"description":"Ad hoc jobs: the job value"},"accountManager":{"type":"string","nullable":true,"maxLength":100},"opportunityId":{"type":"string","nullable":true,"minLength":1,"description":"The deal this contract came from, at the same company; on PATCH null unlinks it"},"hourlyBillZar":{"type":"integer","nullable":true,"minimum":0,"maximum":1000000000,"description":"Bill-out rate per hour: what the client is charged"},"hourlyCostZar":{"type":"integer","nullable":true,"minimum":0,"maximum":1000000000,"description":"Cost rate per hour: what the hour costs Handee"},"noProposal":{"type":"boolean","description":"true = this contract has no proposal, so Handee HQ does not ask for one"},"notes":{"type":"string","nullable":true,"maxLength":2000},"status":{"type":"string","enum":["proposed","active","paused","ended","declined"],"description":"proposed (default) | active | paused | ended | declined"}},"required":["companyId","name","startAt"],"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"},"billing":{"type":"string"},"monthlyZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"termMonths":{"type":"integer","nullable":true},"totalZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"accountManager":{"type":"string","nullable":true},"startAt":{"type":"string"},"endAt":{"type":"string","nullable":true},"hourlyBillZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"hourlyCostZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"noProposal":{"type":"boolean"},"company":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"href":{"type":"string"}},"required":["id","name","status","billing","monthlyZar","termMonths","totalZar","accountManager","startAt","endAt","hourlyBillZar","hourlyCostZar","noProposal","company","createdAt","updatedAt","href"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}}},"/contracts/{id}":{"get":{"summary":"One contract with its documents","description":"Needs a key with read scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}},"patch":{"summary":"Update a contract: status, dates, fee, hourly rates, account manager, the deal it came from","description":"Needs a key with write scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"billing":{"type":"string","enum":["retainer","once_off"],"default":"retainer","description":"retainer (monthly fee for a term) or once_off (ad hoc job)"},"endAt":{"type":"string","nullable":true,"pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Leave out for an open-ended retainer","example":"2026-01-31"},"monthlyZar":{"type":"integer","nullable":true,"minimum":0,"maximum":1000000000,"description":"Retainers: the monthly fee; the term value is monthly × months"},"valueZar":{"type":"integer","nullable":true,"minimum":0,"maximum":1000000000,"description":"Ad hoc jobs: the job value"},"accountManager":{"type":"string","nullable":true,"maxLength":100},"opportunityId":{"type":"string","nullable":true,"minLength":1,"description":"The deal this contract came from, at the same company; on PATCH null unlinks it"},"hourlyBillZar":{"type":"integer","nullable":true,"minimum":0,"maximum":1000000000,"description":"Bill-out rate per hour: what the client is charged"},"hourlyCostZar":{"type":"integer","nullable":true,"minimum":0,"maximum":1000000000,"description":"Cost rate per hour: what the hour costs Handee"},"noProposal":{"type":"boolean","description":"true = this contract has no proposal, so Handee HQ does not ask for one"},"notes":{"type":"string","nullable":true,"maxLength":2000},"status":{"type":"string","enum":["proposed","active","paused","ended","declined"],"description":"proposed (default) | active | paused | ended | declined"},"startAt":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-01-31"}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"},"billing":{"type":"string"},"monthlyZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"termMonths":{"type":"integer","nullable":true},"totalZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"accountManager":{"type":"string","nullable":true},"startAt":{"type":"string"},"endAt":{"type":"string","nullable":true},"hourlyBillZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"hourlyCostZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"noProposal":{"type":"boolean"},"company":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"href":{"type":"string"}},"required":["id","name","status","billing","monthlyZar","termMonths","totalZar","accountManager","startAt","endAt","hourlyBillZar","hourlyCostZar","noProposal","company","createdAt","updatedAt","href"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}}},"/employees":{"get":{"summary":"List employees with current rates","description":"Needs a key with read scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"description":"The nextCursor from the previous page"},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50,"description":"Rows per page, 1 to 100"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"description":"Free-text search"},"required":false,"name":"q","in":"query"},{"schema":{"type":"string","enum":["active","notice","ended"]},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-01-31"},"required":false,"name":"endsFrom","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-01-31"},"required":false,"name":"endsTo","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"fullName":{"type":"string"},"email":{"type":"string","nullable":true},"jobTitle":{"type":"string","nullable":true},"employmentType":{"type":"string"},"status":{"type":"string"},"startAt":{"type":"string"},"endAt":{"type":"string","nullable":true},"costRateZar":{"type":"number","nullable":true,"description":"Current cost rate per hour"},"billRateZar":{"type":"number","nullable":true,"description":"Current bill rate per hour"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"href":{"type":"string"}},"required":["id","fullName","email","jobTitle","employmentType","status","startAt","endAt","costRateZar","billRateZar","createdAt","updatedAt","href"]}},"nextCursor":{"type":"string","nullable":true},"total":{"type":"integer","description":"Rows matching the filters, across all pages"}},"required":["items","nextCursor","total"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}}},"/employees/{id}":{"get":{"summary":"One employee with rates and documents","description":"Needs a key with read scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}}},"/documents":{"get":{"summary":"List documents on a company, deal, contract or employee, oldest first (sort by docDate for the latest)","description":"Needs a key with read scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"description":"The nextCursor from the previous page"},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50,"description":"Rows per page, 1 to 100"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"description":"Free-text search"},"required":false,"name":"q","in":"query"},{"schema":{"type":"string","minLength":1},"required":false,"name":"companyId","in":"query"},{"schema":{"type":"string","minLength":1},"required":false,"name":"opportunityId","in":"query"},{"schema":{"type":"string","minLength":1},"required":false,"name":"contractId","in":"query"},{"schema":{"type":"string","minLength":1},"required":false,"name":"employeeId","in":"query"},{"schema":{"type":"string","minLength":1,"description":"Client documents: nda, terms, quote, status_report, proposal, contract, client_form, other. Employee documents: contract, nda, cv, review, id_document, other."},"required":false,"name":"type","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["client","employee"]},"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"string","nullable":true},"fileName":{"type":"string","nullable":true},"contentType":{"type":"string","nullable":true},"fileSize":{"type":"number","nullable":true},"externalUrl":{"type":"string","nullable":true},"docDate":{"type":"string","nullable":true},"companyId":{"type":"string","nullable":true},"opportunityId":{"type":"string","nullable":true},"contractId":{"type":"string","nullable":true},"employeeId":{"type":"string","nullable":true},"createdAt":{"type":"string"},"period":{"type":"string","nullable":true,"description":"Status reports: the month covered, YYYY-MM"},"fileUrl":{"type":"string","nullable":true,"description":"GET with the API key to download the bytes; add ?preview=1 for a PDF rendering of Office files"},"href":{"type":"string"}},"required":["id","kind","type","title","status","fileName","contentType","fileSize","externalUrl","docDate","companyId","opportunityId","contractId","employeeId","createdAt","period","fileUrl","href"]}},"nextCursor":{"type":"string","nullable":true},"total":{"type":"integer","description":"Rows matching the filters, across all pages"}},"required":["items","nextCursor","total"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"summary":"Attach a document: text rendered to DOCX/PDF, a base64 file, or a link; named by the standard convention","description":"Needs a key with write scope.","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"companyId":{"type":"string","minLength":1,"description":"Attach to the company itself: nda, terms, client_form, other"},"opportunityId":{"type":"string","minLength":1,"description":"Attach to a deal: proposal, quote"},"contractId":{"type":"string","minLength":1,"description":"Attach to a contract: proposal, quote, status_report, contract, other (quote is the services schedule)"},"employeeId":{"type":"string","minLength":1,"description":"Attach to an employee: contract, nda, cv, review, id_document, other"},"type":{"type":"string","minLength":1,"description":"Kind of document. Client: nda, terms, quote, status_report, proposal, contract, client_form, other. Employee: contract, nda, cv, review, id_document, other. Each kind goes in its own place (see the ids); a kind sent to the wrong place is refused with where it belongs. Slots replace the previous document of the same kind."},"title":{"type":"string","maxLength":200,"description":"Used for the file name of 'other' documents; slot kinds are named automatically (Company – Contract – Kind)"},"content":{"type":"string","maxLength":400000,"description":"Markdown or plain text; rendered to DOCX (default) or PDF on the server"},"format":{"type":"string","enum":["docx","pdf","md"],"description":"For content: docx (default), pdf or md"},"contentBase64":{"type":"string","maxLength":21000000,"description":"A file's bytes, base64 encoded (up to 15 MB)"},"fileName":{"type":"string","maxLength":200,"description":"File name, required with contentBase64"},"contentType":{"type":"string","maxLength":100},"externalUrl":{"type":"string","format":"uri","description":"A link instead of a file"},"status":{"type":"string","enum":["draft","sent","received","accepted","declined","sent_for_signature","signed","expired"],"description":"Leave out for the kind's usual status (draft, sent…). Each kind has its own: nda: draft/sent_for_signature/signed/declined/expired; terms: draft/sent_for_signature/signed/declined/expired; quote: draft/sent/accepted/declined; proposal: draft/sent/accepted/declined; contract: draft/sent_for_signature/signed/declined/expired; status_report: draft/sent/received; client_form: draft/sent/received; other: draft/sent/received; employee documents: draft/sent_for_signature/signed/declined/expired/received. A signed services schedule or proposal is accepted."},"docDate":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-01-31"},"period":{"type":"string","pattern":"^\\d{4}-(0[1-9]|1[0-2])$","description":"Status reports: the month covered (YYYY-MM); defaults to docDate's month, else the current month. One report per month per contract; a second replaces it.","example":"2026-09"},"notes":{"type":"string","nullable":true,"maxLength":2000}},"required":["type"],"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["client","employee"]},"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"string","nullable":true},"fileName":{"type":"string","nullable":true},"contentType":{"type":"string","nullable":true},"fileSize":{"type":"number","nullable":true},"externalUrl":{"type":"string","nullable":true},"docDate":{"type":"string","nullable":true},"companyId":{"type":"string","nullable":true},"opportunityId":{"type":"string","nullable":true},"contractId":{"type":"string","nullable":true},"employeeId":{"type":"string","nullable":true},"createdAt":{"type":"string"},"period":{"type":"string","nullable":true,"description":"Status reports: the month covered, YYYY-MM"},"fileUrl":{"type":"string","nullable":true,"description":"GET with the API key to download the bytes; add ?preview=1 for a PDF rendering of Office files"},"href":{"type":"string"}},"required":["id","kind","type","title","status","fileName","contentType","fileSize","externalUrl","docDate","companyId","opportunityId","contractId","employeeId","createdAt","period","fileUrl","href"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}}},"/documents/{id}":{"get":{"summary":"One document's details (its bytes are at /documents/{id}/file)","description":"Needs a key with read scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["client","employee"]},"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"string","nullable":true},"fileName":{"type":"string","nullable":true},"contentType":{"type":"string","nullable":true},"fileSize":{"type":"number","nullable":true},"externalUrl":{"type":"string","nullable":true},"docDate":{"type":"string","nullable":true},"companyId":{"type":"string","nullable":true},"opportunityId":{"type":"string","nullable":true},"contractId":{"type":"string","nullable":true},"employeeId":{"type":"string","nullable":true},"createdAt":{"type":"string"},"period":{"type":"string","nullable":true,"description":"Status reports: the month covered, YYYY-MM"},"fileUrl":{"type":"string","nullable":true,"description":"GET with the API key to download the bytes; add ?preview=1 for a PDF rendering of Office files"},"href":{"type":"string"}},"required":["id","kind","type","title","status","fileName","contentType","fileSize","externalUrl","docDate","companyId","opportunityId","contractId","employeeId","createdAt","period","fileUrl","href"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}},"delete":{"summary":"Remove a document and its file","description":"Needs a key with write scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"id":{"type":"string"}},"required":["ok","id"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}}},"/documents/{id}/send-for-signature":{"post":{"summary":"Send a document to e-sign: a client's services schedule, NDA, terms or contract to a contact, or an employee's contract, NDA or review to the employee (Handee countersigns); the signed PDF replaces the document when done. Proposals are not signed.","description":"Needs a key with write scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"contactId":{"type":"string","minLength":1,"description":"Client documents: the contact at the company who signs (needs an email on file)"},"signerName":{"type":"string","maxLength":200,"description":"With signerEmail: the signer's name, when not a contact. Employee documents default to the employee."},"signerEmail":{"type":"string","format":"email","description":"The signer's email, when not a contact. Employee documents default to the employee's email."},"countersign":{"type":"boolean","description":"Handee countersigns after the client (default true)"},"countersignerName":{"type":"string","maxLength":200},"countersignerEmail":{"type":"string","format":"email","description":"Who countersigns; defaults to the first admin user"},"subject":{"type":"string","maxLength":200,"description":"The signing email's subject; defaults to 'Company: title to sign'"},"message":{"type":"string","maxLength":2000,"description":"A note in the signing email"},"fields":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":40},"signer":{"type":"string","enum":["signer","countersigner"]},"type":{"type":"string","enum":["SIGNATURE","INITIALS","NAME","TITLE","DATE","PLACE","EMAIL","TEXT","COMPANY_NAME","REG_NUMBER","ADDRESS","COMPANY_EMAIL","PERSON_NAME","ID_NUMBER","PERSON_ADDRESS","PERSON_EMAIL","PERSON_PHONE"]},"page":{"type":"integer","minimum":1},"positionX":{"type":"number","minimum":0,"maximum":100},"positionY":{"type":"number","minimum":0,"maximum":100},"width":{"type":"number","minimum":1,"maximum":100},"height":{"type":"number","minimum":1,"maximum":100},"everyPage":{"type":"boolean"},"lastPage":{"type":"boolean"}},"required":["id","signer","type","page","positionX","positionY","width","height"]},"maxItems":200,"description":"Where the fields go, as percentages of the page (positionX/positionY from the top left, width/height), each for the 'signer' or the 'countersigner': SIGNATURE, INITIALS, NAME, TITLE, DATE, PLACE, EMAIL or TEXT, plus COMPANY_NAME, REG_NUMBER, ADDRESS and COMPANY_EMAIL which Handee HQ fills from the company record on a client document, and PERSON_NAME, ID_NUMBER, PERSON_ADDRESS, PERSON_EMAIL and PERSON_PHONE filled from the employee record on an employee document. Set everyPage on a field (initials, say) to repeat it at the same spot on every page, or lastPage to keep it on the last page whatever the page count. A field on a page past the end of the document goes on its last page. Without it the layout saved as the standard for that kind of document is used, or else the standard blocks (signature, name & surname, title, date and place for each person) go at the bottom of the last page. People place them by hand on the document's Send page in Handee HQ."},"handeeOnly":{"type":"boolean","description":"The signer has already signed (the file on record is their signed copy, e.g. a scan): only Handee's countersigner signs, the signer is copied and Documenso emails them the signed PDF once Handee has signed. Only the countersigner's fields go out; the request starts as partially_signed."},"placeFieldsFirst":{"type":"boolean","description":"Create the envelope with the recipients and the blocks but do not send it: the request comes back as draft with externalUrl pointing at Documenso's editor. Normally not needed; fields are placed in Handee HQ."}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","description":"draft | sent | viewed | partially_signed | signed | declined | cancelled | expired | failed"},"documentId":{"type":"string"},"signerName":{"type":"string"},"signerEmail":{"type":"string"},"countersignerName":{"type":"string","nullable":true},"countersignerEmail":{"type":"string","nullable":true},"handeeOnly":{"type":"boolean","description":"Only Handee signs; the signer signed before it went out and is copied on the signed PDF"},"sentAt":{"type":"string","nullable":true},"viewedAt":{"type":"string","nullable":true},"clientSignedAt":{"type":"string","nullable":true},"completedAt":{"type":"string","nullable":true},"declineReason":{"type":"string","nullable":true},"externalUrl":{"type":"string","nullable":true,"description":"The envelope on the signing service"},"error":{"type":"string","nullable":true},"originalUrl":{"type":"string","nullable":true,"description":"The unsigned file, once the signed PDF has replaced it"}},"required":["id","status","documentId","signerName","signerEmail","countersignerName","countersignerEmail","handeeOnly","sentAt","viewedAt","clientSignedAt","completedAt","declineReason","externalUrl","error","originalUrl"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}}},"/documents/{id}/signature":{"get":{"summary":"Where a document's signature request stands","description":"Needs a key with read scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}},"delete":{"summary":"Withdraw an open signature request (one already signed or declined in Documenso is filed as that instead; check the status returned)","description":"Needs a key with write scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","description":"draft | sent | viewed | partially_signed | signed | declined | cancelled | expired | failed"},"documentId":{"type":"string"},"signerName":{"type":"string"},"signerEmail":{"type":"string"},"countersignerName":{"type":"string","nullable":true},"countersignerEmail":{"type":"string","nullable":true},"handeeOnly":{"type":"boolean","description":"Only Handee signs; the signer signed before it went out and is copied on the signed PDF"},"sentAt":{"type":"string","nullable":true},"viewedAt":{"type":"string","nullable":true},"clientSignedAt":{"type":"string","nullable":true},"completedAt":{"type":"string","nullable":true},"declineReason":{"type":"string","nullable":true},"externalUrl":{"type":"string","nullable":true,"description":"The envelope on the signing service"},"error":{"type":"string","nullable":true},"originalUrl":{"type":"string","nullable":true,"description":"The unsigned file, once the signed PDF has replaced it"}},"required":["id","status","documentId","signerName","signerEmail","countersignerName","countersignerEmail","handeeOnly","sentAt","viewedAt","clientSignedAt","completedAt","declineReason","externalUrl","error","originalUrl"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}}},"/documents/{id}/signature/remind":{"post":{"summary":"Send the signing email again to whoever has not signed","description":"Needs a key with write scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","description":"draft | sent | viewed | partially_signed | signed | declined | cancelled | expired | failed"},"documentId":{"type":"string"},"signerName":{"type":"string"},"signerEmail":{"type":"string"},"countersignerName":{"type":"string","nullable":true},"countersignerEmail":{"type":"string","nullable":true},"handeeOnly":{"type":"boolean","description":"Only Handee signs; the signer signed before it went out and is copied on the signed PDF"},"sentAt":{"type":"string","nullable":true},"viewedAt":{"type":"string","nullable":true},"clientSignedAt":{"type":"string","nullable":true},"completedAt":{"type":"string","nullable":true},"declineReason":{"type":"string","nullable":true},"externalUrl":{"type":"string","nullable":true,"description":"The envelope on the signing service"},"error":{"type":"string","nullable":true},"originalUrl":{"type":"string","nullable":true,"description":"The unsigned file, once the signed PDF has replaced it"}},"required":["id","status","documentId","signerName","signerEmail","countersignerName","countersignerEmail","handeeOnly","sentAt","viewedAt","clientSignedAt","completedAt","declineReason","externalUrl","error","originalUrl"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}}},"/canvas":{"get":{"summary":"Files waiting on the Canvas to be filed","description":"Needs a key with read scope.","security":[{"apiKey":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"createdAt":{"type":"string"},"fileName":{"type":"string","nullable":true},"contentType":{"type":"string","nullable":true},"fileSize":{"type":"number","nullable":true},"externalUrl":{"type":"string","nullable":true},"title":{"type":"string","nullable":true},"note":{"type":"string","nullable":true},"source":{"type":"string"},"sentBy":{"type":"string"},"suggestedType":{"type":"string","nullable":true},"suggestedCompanyName":{"type":"string","nullable":true},"suggestedTarget":{"type":"string","nullable":true},"suggestedPeriod":{"type":"string","nullable":true},"fileUrl":{"type":"string","nullable":true},"href":{"type":"string"}},"required":["id","createdAt","fileName","contentType","fileSize","externalUrl","title","note","source","sentBy","suggestedType","suggestedCompanyName","suggestedTarget","suggestedPeriod","fileUrl","href"]}},"total":{"type":"integer"}},"required":["items","total"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"summary":"Drop a file on the Canvas to be filed later: text rendered to DOCX/PDF, a base64 file, or a link, with a note and hints","description":"Needs a key with write scope.","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","maxLength":200,"description":"Used for the file name of 'other' documents; slot kinds are named automatically (Company – Contract – Kind)"},"content":{"type":"string","maxLength":400000,"description":"Markdown or plain text; rendered to DOCX (default) or PDF on the server"},"format":{"type":"string","enum":["docx","pdf","md"],"description":"For content: docx (default), pdf or md"},"contentBase64":{"type":"string","maxLength":21000000,"description":"A file's bytes, base64 encoded (up to 15 MB)"},"fileName":{"type":"string","maxLength":200,"description":"File name, required with contentBase64"},"contentType":{"type":"string","maxLength":100},"externalUrl":{"type":"string","format":"uri","description":"A link instead of a file"},"period":{"type":"string","pattern":"^\\d{4}-(0[1-9]|1[0-2])$","description":"Status reports: the month covered (YYYY-MM), kept as a hint for whoever files it","example":"2026-09"},"note":{"type":"string","nullable":true,"maxLength":2000,"description":"What this is and who it is for, e.g. 'Proposal for Crestpac, agile team Q4'"},"suggestedType":{"type":"string","maxLength":40,"description":"A guess at the kind: proposal, quote, nda, terms, client_form, status_report, contract, other"},"suggestedCompany":{"type":"string","maxLength":200,"description":"Company name it probably belongs to"},"suggestedTarget":{"type":"string","maxLength":200,"description":"Deal or contract name it probably belongs to"}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"createdAt":{"type":"string"},"fileName":{"type":"string","nullable":true},"contentType":{"type":"string","nullable":true},"fileSize":{"type":"number","nullable":true},"externalUrl":{"type":"string","nullable":true},"title":{"type":"string","nullable":true},"note":{"type":"string","nullable":true},"source":{"type":"string"},"sentBy":{"type":"string"},"suggestedType":{"type":"string","nullable":true},"suggestedCompanyName":{"type":"string","nullable":true},"suggestedTarget":{"type":"string","nullable":true},"suggestedPeriod":{"type":"string","nullable":true},"fileUrl":{"type":"string","nullable":true},"href":{"type":"string"}},"required":["id","createdAt","fileName","contentType","fileSize","externalUrl","title","note","source","sentBy","suggestedType","suggestedCompanyName","suggestedTarget","suggestedPeriod","fileUrl","href"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}}},"/canvas/{id}/file":{"post":{"summary":"File a Canvas item onto a company, deal, contract or employee as a kind of document","description":"Needs a key with write scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"companyId":{"type":"string","minLength":1},"opportunityId":{"type":"string","minLength":1},"contractId":{"type":"string","minLength":1},"employeeId":{"type":"string","minLength":1},"type":{"type":"string","minLength":1,"description":"Kind of document to file it as"},"title":{"type":"string","maxLength":200},"status":{"type":"string","enum":["draft","sent","received","accepted","declined","sent_for_signature","signed","expired"]},"period":{"type":"string","pattern":"^\\d{4}-(0[1-9]|1[0-2])$","description":"Status reports: the month covered (YYYY-MM); defaults to the drop's hint, else the current month","example":"2026-09"}},"required":["type"],"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["client","employee"]},"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"string","nullable":true},"fileName":{"type":"string","nullable":true},"contentType":{"type":"string","nullable":true},"fileSize":{"type":"number","nullable":true},"externalUrl":{"type":"string","nullable":true},"docDate":{"type":"string","nullable":true},"companyId":{"type":"string","nullable":true},"opportunityId":{"type":"string","nullable":true},"contractId":{"type":"string","nullable":true},"employeeId":{"type":"string","nullable":true},"createdAt":{"type":"string"},"period":{"type":"string","nullable":true,"description":"Status reports: the month covered, YYYY-MM"},"fileUrl":{"type":"string","nullable":true,"description":"GET with the API key to download the bytes; add ?preview=1 for a PDF rendering of Office files"},"href":{"type":"string"}},"required":["id","kind","type","title","status","fileName","contentType","fileSize","externalUrl","docDate","companyId","opportunityId","contractId","employeeId","createdAt","period","fileUrl","href"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}}},"/canvas/{id}":{"delete":{"summary":"Discard a Canvas item","description":"Needs a key with write scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"id":{"type":"string"},"removed":{"type":"boolean"}},"required":["ok","id","removed"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}}},"/money":{"get":{"summary":"Money summary for a year","description":"Needs a key with read scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"integer","minimum":2000,"maximum":2100,"description":"Calendar year; default this year"},"required":false,"name":"year","in":"query"},{"schema":{"type":"string","minLength":1},"required":false,"name":"companyId","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"year":{"type":"integer"},"contractedByStartYearZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"inYearZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"runRateMonthlyZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"wonInYearZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"wonInYearDeals":{"type":"integer"},"note":{"type":"string"},"company":{"type":"string","description":"With companyId: the company"},"companyId":{"type":"string"},"href":{"type":"string"},"contracts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"company":{"type":"string"},"status":{"type":"string","description":"Wording for people, e.g. \"Active\"; PATCH takes statusValue"},"statusValue":{"type":"string","enum":["proposed","active","paused","ended","declined"]},"billing":{"type":"string","description":"Wording for people, e.g. \"Ad hoc job\"; PATCH takes billingValue"},"billingValue":{"type":"string","enum":["retainer","once_off"]},"monthlyZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"totalZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"termMonths":{"type":"integer","nullable":true},"startAt":{"type":"string","nullable":true,"description":"YYYY-MM-DD"},"endAt":{"type":"string","nullable":true,"description":"YYYY-MM-DD"},"accountManager":{"type":"string","nullable":true},"href":{"type":"string"},"inYearZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"}},"required":["id","name","status","statusValue","billing","billingValue","monthlyZar","totalZar","termMonths","startAt","endAt","accountManager","href","inYearZar"]},"description":"With companyId: its contracts"},"contractsStartingInYear":{"type":"integer"},"activeContracts":{"type":"integer"},"pipelineZar":{"type":"integer","nullable":true,"description":"Rand, whole numbers"},"openDeals":{"type":"integer"}},"required":["year","contractedByStartYearZar","inYearZar","runRateMonthlyZar","wonInYearZar","wonInYearDeals","note"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}}},"/due":{"get":{"summary":"What needs attention: contracts and employee agreements ending within 60 days (or past their end while still open), and documents sent for signature waiting 7 days or more","description":"Needs a key with read scope.","security":[{"apiKey":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"total":{"type":"integer"},"rows":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["job_end","employee_contract","signature_pending"]},"label":{"type":"string","description":"Client contract ending, Employee contract ending or Signature waiting"},"title":{"type":"string"},"detail":{"type":"string"},"endsOn":{"type":"string","nullable":true,"description":"Contracts: the end date (YYYY-MM-DD); null for a signature"},"daysLeft":{"type":"integer","nullable":true,"description":"Contracts: days until the end, negative once passed; null for a signature"},"sentOn":{"type":"string","nullable":true,"description":"Signatures: the day it was sent (YYYY-MM-DD); null for a contract"},"daysWaiting":{"type":"integer","nullable":true,"description":"Signatures: days since it was sent; null for a contract"},"when":{"type":"string","description":"In words, e.g. 'ends in 12 days' or 'sent 9 days ago'"},"severity":{"type":"string","enum":["overdue","soon","upcoming"]},"href":{"type":"string"}},"required":["kind","label","title","detail","endsOn","daysLeft","sentOn","daysWaiting","when","severity","href"]}},"href":{"type":"string"}},"required":["total","rows","href"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}}},"/activities":{"post":{"summary":"Log an activity (note, email, call, meeting, linkedin) against a contact or company","description":"Needs a key with write scope.","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["note","email","call","meeting","linkedin"]},"contactId":{"type":"string","nullable":true,"minLength":1},"companyId":{"type":"string","nullable":true,"minLength":1,"description":"Needed only when there is no contactId"},"opportunityId":{"type":"string","nullable":true,"minLength":1},"occurredAt":{"type":"string","format":"date-time","description":"ISO 8601; default now"},"subject":{"type":"string","nullable":true,"maxLength":200},"body":{"type":"string","nullable":true,"maxLength":2000}},"required":["type"],"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"occurredAt":{"type":"string"},"subject":{"type":"string","nullable":true},"body":{"type":"string","nullable":true},"contactId":{"type":"string","nullable":true},"companyId":{"type":"string","nullable":true},"opportunityId":{"type":"string","nullable":true},"authorName":{"type":"string","nullable":true},"createdAt":{"type":"string"}},"required":["id","type","occurredAt","subject","body","contactId","companyId","opportunityId","authorName","createdAt"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key does not have the scope this needs","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"nullable":true}},"required":["code","message"]}},"required":["error"]}}}}}}}}}