EngageCycle API
Base address: https://app.engagecycle.com/api/v1. Send Authorization: Bearer <your API key> with every request. Keys are made by owners in Integrations, API keys. Events sent to your webhook, and how to check their signature, are in Webhooks.
Not covered yet: agreements and consents sent on their own, and walkthroughs. Their webhook events are sent as usual.
The API lets your own tools (n8n, Zapier, a script) do what your team does in EngageCycle: keep clients and the catalog up to date, make proposals, preview them, and send them, and follow what happens to them. Every endpoint is listed in the reference below this guide, and the machine-readable description is /api/v1/openapi.json (OpenAPI 3.1, readable without a key). Each operation in it carries its scope as x-scope (null for any key).
Authentication
Every request carries your API key:
Authorization: Bearer <your API key>
An owner makes keys in Integrations, API keys. A key is shown once, when it's made; EngageCycle keeps only a fingerprint of it. Turn a key off there as soon as you stop using it. The base address is https://app.engagecycle.com/api/v1.
Scopes
A key can do only what was ticked when it was made. Keys made before scopes existed have full access and are labelled "Full access (legacy)"; make a new key to narrow one.
| Scope | What it allows |
|---|---|
clients:read |
Read clients |
clients:write |
Add, change, archive, restore, and import clients; set who must sign; add, change, and remove a client's people |
proposals:read |
Read proposals, previews, and signed PDFs |
proposals:write |
Make and change drafts, preview, revise, remove a copied person's access, record handoffs and bookings |
proposals:send |
Send, resend, and withdraw proposals, extend their deadlines, and send a copied person their copy again |
proposals:links |
Read a client's signing link, and the links inside events from GET /events (each read is in the activity log) |
catalog:read |
Read the catalog, templates, and presets |
catalog:write |
Add and change catalog items, but not their prices |
catalog:prices |
Set and change catalog prices (with catalog:write) |
campaigns:read |
Read campaigns |
offers:read |
Read offers and their leads |
events:read |
Read events |
events:write |
Send an event to your webhook again |
documents:read |
Read agreements, consents, and their signed PDFs, and their document.* events from GET /events |
GET /me and GET /credits work with any key. A missing scope is 403 missing_scope, and the error's scope names the one needed. Two routes need a second scope only for part of what they do: setting or changing a price on POST /catalog or PATCH /catalog/{id} needs catalog:prices as well as catalog:write, and GET /events with a document.* type needs documents:read as well as events:read.
Money, times, and ids
- Money is a whole number of the smallest unit of your business's currency (cents for USD), with the
currencybeside it:45000withUSDis $450.00.unit_cents: nullmeans no price has been set yet, which is different from0(shown to clients as "Included"). - Times are ISO 8601 in UTC, like
2026-10-08T14:30:00.000Z. - Ids are UUIDs. Event ids are
evt_followed by 32 hexadecimal characters, the same as the webhook's.
Lists and pages
Lists answer { "data": [...], "next_cursor": "..." }. Ask for up to 200 at a time with ?limit= (50 if you don't say), and pass next_cursor back as ?cursor= for the next page. next_cursor is null on the last page. A cursor is a position, not a page number, so a page never repeats or skips anything when new records arrive while you're reading. Lists are newest first, except events.
Leads and prospects
GET /leads (scope offers:read) lists the people who started one of your offers. A lead's status is one of started (hasn't confirmed their email), verified (confirmed, with a proposal), signed, abandoned, discarded, converted_existing (sent to a proposal they already had), and, on an offer that holds requests for review, awaiting_review, declined_by_business, and review_expired. Filter with ?status=, ?offer_id=, or ?created_since=.
Someone who confirms their email on an offer isn't one of your clients until they sign (or you add them): GET /clients leaves them out, and GET /clients/{id} answers 404 for them. A lead's client_id names their record either way. POST /clients with a prospect's email adds a separate client and leaves the prospect as they are; they become a client when they sign.
One email can belong to more than one client (decided 2026-10-24): a person and their business often share one. POST /clients with an email already in use still adds the client, and its answer's email_shared_with lists the other clients' ids (empty when none). GET /clients?email= returns every client with that email. Imports match by email only when exactly one client has it; a row without an external_id whose email more than one client uses is refused with "More than one client uses this email. Add an ID column to say which one."
Idempotency
Send an Idempotency-Key header (any unique text up to 200 characters, for example the n8n execution id plus a step name) when you create or send something. It's required on:
POST /clientsPOST /clients/{id}/peoplePOST /catalogPOST /proposalsPOST /proposals/{id}/sendPOST /proposals/{id}/resendPOST /proposals/{id}/extendPOST /proposals/{id}/revisePOST /proposals/{id}/copied/{personId}/resend
and accepted on every other POST, PATCH, and DELETE. If the same request arrives again with the same key within 24 hours, you get the first answer back, with the header Idempotent-Replayed: true, and nothing is done twice: a retried send never sends a second time. That includes an error: a request refused with a key is refused again with that key, so use a new key once you have fixed the cause. The same key with a different request is 422 idempotency_key_reused; a key whose first request is still running is 409 idempotency_in_progress.
Errors
Every error has the same shape:
{ "error": { "code": "preview_changed", "message": "This changed since your preview. Preview it again.", "field": "build.packages.0.items.1.qty" } }
Branch on code; message is written for a person, and field (when present) names the input at fault. A few codes add one more field: missing_scope has scope, unknown_columns has columns, and internal_error has request_id.
| Status | Codes | What happened |
|---|---|---|
| 400 | invalid_body, invalid_query, validation |
Something in the request isn't right; see field and details |
| 400 | sensitive_value |
A value looks like a Social Security number, ITIN, or EIN. EngageCycle never stores government ID numbers |
| 400 | idempotency_key_required |
This request needs an Idempotency-Key |
| 401 | unauthorized |
No key, or a key that's wrong or turned off |
| 402 | out_of_credits |
Sending needs a credit and there's none left |
| 403 | missing_scope |
The key doesn't have the scope this needs |
| 403 | not_on_plan |
Your plan doesn't include the API |
| 403 | forbidden |
Your plan doesn't include what this needs (Multiple signers, or Agreement and Consent for documents) |
| 403 | paused, closed |
The business is paused or closed: reading still works, changes are refused |
| 403 | deleted |
The business is being deleted: nothing works |
| 404 | not_found |
No such record in your business |
| 404 | no_open_proposal |
POST /bookings/match: that email has no open proposal |
| 409 | invalid_state |
It can't be done now (for example, changing a proposal that was already sent) |
| 409 | idempotency_in_progress |
A request with this Idempotency-Key is still running |
| 409 | not_previewed, preview_changed, preview_stale |
Send needs a fresh preview; see below |
| 409 | send_blocked |
Email is paused, or your email sender isn't ready |
| 409 | conflict |
Something else is already using that name or id |
| 409 | webhook_off |
Your webhook isn't on, so an event can't be resent |
| 409 | pdf_not_ready, not_signed |
The signed PDF isn't there yet |
| 413 | too_large, too_many_rows |
The request is too big: over 1 MB (10 MB for /clients/batch and /clients/import), or over 5,000 rows in an import |
| 422 | unknown_columns |
An import has a column no client field takes; columns lists them |
| 422 | idempotency_key_reused |
This Idempotency-Key was used for a different request |
| 429 | rate_limited |
Too many requests; wait Retry-After seconds |
| 500 | internal_error |
Something went wrong on our side; request_id helps support find it |
Rate limits
Each key may make 120 requests a minute. Every answer carries X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset (when the minute ends, in Unix seconds). Over the limit you get 429 rate_limited with Retry-After.
Sending a proposal
A proposal goes out in three steps, the same as in the admin:
- Make a draft:
POST /proposalswith aclient_id, and either apreset_id(a preset, from Catalog > Presets) or abuild. Without atemplate_idit uses your default template. On 2026-10-24/presetsandpreset_idreplaced the address/saved-buildsand the fieldsaved_build_id, which now answer 404 andinvalid_body. - Preview it:
POST /proposals/{id}/preview. This freezes exactly what the client will see, fixes the respond-by date, and returnspreview_sha256. You can look at the document atdocument_url(with your key). - Send it:
POST /proposals/{id}/sendwith thatpreview_sha256andemail: true(EngageCycle emails the link) oremail: false(the link is made and nothing is emailed; read it withGET /proposals/{id}/link, which needsproposals:links).
Send refuses with not_previewed when there's no preview, preview_changed when the draft, template, branding, or client changed since the preview, and preview_stale when the preview is from an earlier day (or over 24 hours old): preview again and send the new hash. Sending uses one credit; the answer says how many are left.
Resending the link: POST /proposals/{id}/resend (proposals:send, with an Idempotency-Key) does what Resend does in the admin. The client gets a new link, emailed when you have an email sender (otherwise proposal.sent with is_resend: true tells your automation), and their earlier links stop working. An expired proposal reopens only within 30 days of its deadline: its deadline is extended first (to expiry_days from today, logged with the reason "Sent a new link", with its own proposal.deadline_extended event), and the respond-by date the document printed doesn't change. Changed 2026-10-16: Resend used to reopen an expired proposal of any age, and moved the printed date on a campaign's proposal. Now one that ended more than 30 days ago is refused (409 invalid_state, "This ended more than 30 days ago. Start a new one to send it again."), as is a withdrawn one, which stays withdrawn. The answer never holds the link.
Extending the deadline: POST /proposals/{id}/extend (proposals:send, with an Idempotency-Key) gives the client more time on the same proposal. The link they have keeps working, and the document (and its PDF) keeps the respond-by date it printed. The body:
{ "expires_on": "2026-11-20", "reason": "Waiting on documents", "notify_client": true }
expires_onis a date in your business's time zone; the deadline is the end of that day. It must be later than the current deadline, not in the past, and at most 180 days from today. Otherwise it's422 validation("Pick a date after November 5, 2026.", "Pick a date within 180 days (by April 14, 2027).").reason(optional, up to 500 characters) is for your team: it's in the activity and the event, never shown to the client.notify_client(defaulttrue) emails the client (and each other signer whose turn it is) a second link with the new date. Both links work. No credit is used.- An open proposal can be extended any time before its deadline. An expired one can be within 30 days of its deadline, which reopens it (
reopened: true). A draft, a signed, declined, withdrawn, or replaced proposal, one that ended more than 30 days ago, or one in a walkthrough is409 invalid_state(extend a walkthrough from its page in EngageCycle). - The answer is the proposal (its
expires_atis now the new deadline, andoriginal_expires_atthe printed date),reopened, andemailed. It writesproposal.deadline_extended(Webhooks). The answer never holds a link.
expires_at is the effective deadline. Since 2026-10-16 a proposal's expires_at (in the API and every event) is when it really ends, after any extension. An extended proposal also has original_expires_at, the respond-by date its document printed; a proposal that was never extended has no original_expires_at key at all. Documents (GET /documents/{id}) work the same way.
A build in a request is a short form. Packages list catalog items by id (copied as the builder copies them, with an optional unit_cents for this proposal only) or typed items with a name and price. Add-ons name a catalog item or have a name and price, and only_with lists the packages they go with by position (0 is the first). A typed item or add-on takes a billing (one_time, yearly, semiannual, quarterly, monthly, or weekly), and "billed_as_used": true makes it a rate: a price per unit with no quantity, never in a total. Any item or add-on takes a unit_label (free text, up to 40 characters: "form", "hour") and an optional unit_plural (when adding "s" reads wrong: "entities"); a catalog item can be given its own unit for this proposal without changing the catalog. A rate needs a unit: the draft saves without one, and preview refuses until it has one (the build lists them in no_unit). A catalog item keeps its own billing:
{
"client_id": "6f1c...",
"build": {
"mode": "choose",
"packages": [
{ "name": "Standard", "items": [{ "catalog_item_id": "3a9e..." }] },
{
"name": "Premium",
"badge": "Recommended",
"items": [{ "catalog_item_id": "3a9e..." }, { "name": "Planning call", "unit_cents": 15000 }]
}
],
"addons": [{ "catalog_item_id": "77b0...", "kind": "quantity", "max_qty": 5, "only_with": [1] }]
}
}
mode: "fixed" is one price to approve and has exactly one package. Nothing is ever chosen for the client: packages start unselected and add-ons at their minimum.
Totals by billing frequency. Each package in a draft or preview, each preset (GET /presets), and each signature has totals: [{ "billing", "cents" }], a one-time total and then each recurring frequency on its own (yearly, semiannual, quarterly, monthly, weekly), never added together. total_cents (one-time plus yearly) and monthly_cents are kept for compatibility only; amounts billed every six months, quarterly, or weekly are only in totals, so new integrations should read totals. Lines that are rates have billed_as_used: true, with qty and amount_cents of 0. The proposal.signed webhook event carries the same totals.
Discount lines (read-only for now). A proposal can carry discount lines, added in the builder or by a campaign: fixed amounts taken off whatever the client chooses, each in one billing frequency. Over the API they can be read but not set:
- A draft's or preview's build lists them in
discounts(id,discount_idor null for a one-off,kind,label,amount_cents(positive, taken off), andbilling), and each package gainsnet_totals: that package alone, net of them. Without discounts neither key is there. - A signature's
totals,total_cents, andmonthly_centsare what the client agreed to pay, net of discounts. With a discount the signature also hasdiscounts(each line with itskind) andlisted_totals(before them), as inproposal.signed(Webhooks). - A
buildwith adiscountskey is refused (400validation: "Discounts can't be set through the API yet. Add them in the builder."). - A
PATCHwhosebuildreplaces a draft's packages and add-ons keeps the draft's discounts. It's refused (400validation, "A total can't go below zero") when the new packages would leave a total below zero. - MCP's
get_proposalandpreview_proposalshow the same;create_proposalcan't add discounts.
Business clients
A client is an individual or a business. A business is an entity, such as a company or a partnership, and a person signs for it.
- Fields: clients carry
type(individualorbusiness; every client nobody marked reads asindividual),contact_name(at most 120 characters), andcontact_title(at most 80). On a business,display_nameis the business's name,contact_nameis the person you deal with ("Dana Lee"),contact_titleis their title ("Managing Member", the prefill when they sign), andfirst_nameis the contact's first name, filled fromcontact_namewhen you leave it out. There's no separate business name input and no ID number field of any kind. - Setting them:
POST /clientsandPATCH /clients/{id}taketype,contact_name, andcontact_title. Contact fields on an individual are refused with 400validation("contact_name is only for business clients"). Changing a business toindividualremoves its contact and title. Searching clients matches the contact name too. - Imports:
POST /clients/batchand/clients/importtake the columnsclient_type("Individual" or "Business", any case; also "Person", "Personal", "Company", "Entity", "Organization"),business_name,contact_name, andcontact_title. A row with abusiness_nameis a business named for it; with nocontact_name, itsdisplay_nameis the contact. An individual's row with a contact or title still imports, with a warning ("Contact and title are only kept for business clients"). A column a file leaves out keeps the client's value, and a row whoseclient_typeandbusiness_nameare both blank keeps the client's type and contact. - People: a person on a client has an optional
title(at most 80), their title at the business. It's kept on an individual's people too, but used only on a business. - Signed for a business: on a proposal or document whose client was a business when it was sent, the signer types their title, and
GET /proposals/{id}andGET /documents/{id}show the signature'ssigner_title("Managing Member") andon_behalf_of(the business's name). With several signers, each entry insignershassigner_titleandon_behalf_ofonce that signer signed, and a proposal's signers also havetitle, the title staff entered for them (the prefill). The proposal'sclientblock hastype: "business",contact_name, andcontact_title, as the webhook events do (Webhooks). All of these are absent for an individual, never null. - Signed for a represented client: an individual client can have a
representative(name,email, optionalphone, andcapacity:power_of_attorney,guardian,executor, orpersonal_representative), set onPOST /clientsandPATCH /clients/{id}(nullremoves it; refused on a business with 400). Everything for the client is sent to the representative, and the client's ownemailbecomes optional.GET /clients/{id}shows it (absent when the client signs for themselves). Once the representative signs,GET /proposals/{id}andGET /documents/{id}show the signature'ssigner_capacityandon_behalf_of(the client's name), and that signer's entry insignershas them too. The proposal'sclientblock hasrepresentative, as the webhook events do. All absent otherwise. Changing or removing a representative affects only what's sent afterwards. - MCP's
create_clientandupdate_clienttake the same fields;get_clientandsearch_clientsreturn them.
Copied people
A client can have people who are copied on their proposals: a spouse, a family member, an assistant. A copied person gets a view-only link when the proposal is sent and, unless you turn it off, the signed copy. They can never choose, sign, or decline.
- On the client:
GET /clients/{id}/peoplelists them;POST /clients/{id}/peopleadds one,PATCH /clients/{id}/people/{personId}changes one, andDELETE /clients/{id}/people/{personId}stops copying them (clients:write). A person is{ "name", "email", "phone", "title", "relationship", "role" }, whererelationshipisspouse,family,assistant,business_partner, orother, androleiscopied, orsignerwhen the business has Multiple signers (see below; refused with 400 otherwise). - The client asked. Adding someone, or changing their email, needs
"client_asked": true: the client asked you to share their proposals with this person. It's recorded with your key and the time. Sharing is your decision and responsibility. - On a draft: a new draft starts with the client's people.
copied_peopleonPOST /proposalsorPATCH /proposals/{id}is the whole list for that proposal only (people already on it, matched by email, stay as they are; anyone new needsclient_asked; anyone left out is removed), andcopied_signed_copy: falsekeeps the signed copy from them. Changing only these keeps the preview. Once sent, who's copied can't change. - Sending:
email: trueemails copied people their view-only link too. Withemail: false, they're still emailed unless you send"email_copied": false. - Reading:
GET /proposals/{id}hascopied_people, each withlink_sent_at,first_viewed_at,last_viewed_at,view_count, andaccess_removed_at. The webhook'sproposal.sentlists them with theirview_urlwhile it's active (withproposals:linksinGET /events), andproposal.copy_viewedfires the first time each one looks (Webhooks). - Send copy again:
POST /proposals/{id}/copied/{personId}/resend(proposals:send, with an Idempotency-Key) emails them their link again: the same link while the proposal is open, otherwise a new one (their earlier link stops;new_linksays which). It needs your email sender and is refused while email is paused. - Remove access:
POST /proposals/{id}/copied/{personId}/remove-access(proposals:write). Their link says "This link is no longer active", for good, and nothing more is emailed to them. Send their copy again to give them a new link.
Several signers
When the business has Multiple signers on its plan (off on every plan unless EngageCycle turns it on), a proposal can need more than one signature, for example both spouses on a joint return. Each signer signs the same proposal with their own link. With the feature off, everything here is refused ("Multiple signers aren't on your plan."): signing on a draft and a client's default with 403 forbidden, and a person with role: "signer" with 400 validation.
- Who signs: people with
role: "signer"on the client (/clients/{id}/people) or in a draft'scopied_people. At most 4 signers, the client included. - Who must sign:
signing: { "rule": "all" | "any", "order": "any" | "in_order" }onPOST /proposalsorPATCH /proposals/{id}(null goes back to the client's default);POST /clients/{id}/signing { "rule" }sets the client's default, and clients carrysigning_rule. The order applies to All signers only. - Sending: with
email: trueevery signer whose turn it is gets their own link by email (In order, the next one when the one before signs). Withemail: falseevery link is made and nobody is emailed. The signing link the API reads is the client's own. - Reading:
GET /proposals/{id}(and the answers to create and update) hassigningandsigners: [{ "name", "email", "position", "client", "state", "signed_at", "declined_at" }](and, for a business client,title,signer_title, andon_behalf_of; see Business clients);stateiswaiting,open,signed,declined, orvoided(a revised or withdrawn version). With one signersigningis null andsignersis empty. A proposal'sstatusissignedonly once everyone needed has signed, and itssignatureis the agreement: the choice and signing of the signer who chose. The webhook events are in Webhooks.
{
"client_id": "6f1c...",
"copied_people": [
{ "name": "Sam Lin", "email": "[email protected]", "relationship": "family", "client_asked": true }
]
}
Documents: agreements and consents (read-only)
A business can send an agreement (an engagement letter, for example) or a consent on its own, with no price. The API reads them; making and sending one over the API is later. Every route needs the documents:read scope (a key made before scopes, with full access, has it) and Agreement or Consent on the business's plan, else 403 forbidden ("Agreement and Consent templates aren't on your plan.").
GET /documents: newest first, never a draft and never a proposal. Filters:kind(agreementorconsent),status,client_id,since(changed since). Pages like every list.GET /documents/{id}:id,kind,version,status,template(id,name),client(id,external_id,display_name),campaign_id,supersedes_id,sent_at,expires_at,resolved_at,created_at,updated_at,signers(position,client,name,state,signed_at,declined_at; empty with one signer),signatureonce signed (signed_at,typed_name,signing_method, and the consent documents agreed,consents;signer_titleandon_behalf_ofwhen it was signed for a business), andpdf_ready.GET /documents/{id}/pdf: the signed PDF with its certificate,X-EngageCycle-Sha256its hash; 409not_signedorpdf_not_readyotherwise.
Nothing here returns a signing link or anyone's email. The proposal endpoints never show a document: GET /proposals leaves them out, and GET /proposals/{id}, its PDF, handoff, booked, and extend answer 404 for a document's id (extend a document from its page in EngageCycle). Their webhook events are document.* (Webhooks), and GET /events returns them only when you name them in type, with a key that has documents:read as well as events:read. MCP has no document tools yet.
Recipe: n8n, from a new client to a sent proposal
This workflow takes a name and email (from a form, a CRM, or a webhook), finds or adds the client, makes a proposal from a preset, previews it, and sends it. In n8n, make an HTTP Header Auth credential named "EngageCycle" with the name Authorization and the value Bearer <your API key> (scopes: clients:read, clients:write, catalog:read, proposals:write, proposals:send). Every HTTP Request node below uses it, with the base address https://app.engagecycle.com/api/v1.
- Find the client. HTTP Request, GET
/clients, queryemail={{ $json.email }}. - IF
{{ $json.data.length }}is 0, go to step 3. If it's 1, use{{ $json.data[0].id }}as the client id and skip to step 4. More than one means several clients share the email (a person and their business, say): stop and pick by hand, or find the client byexternal_idinstead. - Add the client. HTTP Request, POST
/clients, headerIdempotency-Key={{ $execution.id }}-client, JSON body:
The answer is the client; its id is{ "display_name": "{{ $('Trigger').item.json.name }}", "email": "{{ $('Trigger').item.json.email }}" }{{ $json.id }}. - Pick the preset once. Call GET
/presetsyourself, copy the id of the preset you want, and keep it in the workflow (a Set node,preset_id). - Make the draft. HTTP Request, POST
/proposals, headerIdempotency-Key={{ $execution.id }}-draft, body{ "client_id": "<client id from step 2 or 3>", "preset_id": "<from step 4>" }. Its id is{{ $json.proposal.id }}. - Preview. HTTP Request, POST
/proposals/{{ $json.proposal.id }}/preview. Keep{{ $json.preview_sha256 }}. - Send. HTTP Request, POST
/proposals/<id>/send, headerIdempotency-Key={{ $execution.id }}-send, body{ "preview_sha256": "{{ $json.preview_sha256 }}", "email": true }. If n8n retries the node, the key makes sure the client gets one email.
Turn on "Retry On Fail" for steps 3 to 7: with the idempotency keys, a retry after a timeout is safe. For a 409 preview_changed, go back to step 6. For 402 out_of_credits, stop and tell an owner.
Recipe: polling events instead of a webhook
GET /events lists every event your business records, oldest first, in exactly the shape the webhook sends (id, type, created_at, tenant, data). It's for tools that can't receive webhooks, or as a safety net beside them.
- Call
GET /events?limit=200once and keepnext_cursor. - Every few minutes (an n8n Schedule Trigger), call
GET /events?since=<the cursor you kept>&limit=200, handle each event, and keep the newnext_cursor. When nothing happened,datais empty andnext_cursorstays the same. - Repeat. Filter with
type=proposal.signed(repeattypefor several) orproposal_id=.
An event appears only once everything written before it is finished, so polling never skips one, even when two things happen at the same moment. Usually that is within a second; while a long job is still saving (a large campaign batch, for example), newer events wait until it finishes, and then all arrive in order. Store the event id if you also take the webhook: the same id arrives both ways. Signing links inside proposal.sent and lead.abandoned (signing_url, resume_url) come back as null (with "redacted": true) unless the key has proposals:links. Even then a link is given only while it still works: once the proposal is signed, declined, withdrawn, replaced, or expired, or a newer link was sent, it is null, the same as in the webhook. EngageCycle never keeps the link itself in an event. Each item also says how the webhook delivery went (delivery: delivered, due, failed, or off when it was recorded while the webhook was off), and POST /events/{id}/redeliver (scope events:write) sends one to your webhook again while the webhook is on.
The signed PDF for a proposal.signed event is at data.pdf.url (or GET /proposals/{id}/pdf), and needs your key.
AI assistants (MCP)
The same keys also work with EngageCycle's MCP server, POST https://app.engagecycle.com/mcp, so AI assistants such as Claude and ChatGPT can look up clients and proposals, make drafts, and send them after a preview. It counts against the same 120 requests a minute per key, needs the same scopes, and never returns signing links, even to a key with proposals:links. MCP lists each tool with the scope it needs and has setup you can copy; Integrations, MCP has the same in EngageCycle.
Reference
Account
GET /me
The business and this key
Any key.
Answer 200
GET /credits
Credits left
One credit is one proposal reaching a client for the first time.
Any key.
Answer 200
Templates and presets
GET /templates
List templates proposals can use
Published Proposal templates without prices of their own, newest first.
Scope: catalog:read.
| Parameter | In | Required | About |
|---|---|---|---|
limit | query | no | How many to return, 1 to 200 |
cursor | query | no | The next_cursor from the previous page |
Answer 200
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Template"
}
},
"next_cursor": {
"description": "Pass as cursor (or since, for events) to get the next page; null at the end",
"type": [
"string",
"null"
]
}
},
"required": [
"data",
"next_cursor"
],
"additionalProperties": false
}GET /presets
List presets
Presets: saved sets of services, packages, add-ons, and prices to start a proposal from (preset_id on POST /proposals).
Scope: catalog:read.
| Parameter | In | Required | About |
|---|---|---|---|
limit | query | no | How many to return, 1 to 200 |
cursor | query | no | The next_cursor from the previous page |
archived | query | no | One of true, false |
Answer 200
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Preset"
}
},
"next_cursor": {
"description": "Pass as cursor (or since, for events) to get the next page; null at the end",
"type": [
"string",
"null"
]
}
},
"required": [
"data",
"next_cursor"
],
"additionalProperties": false
}Campaigns and offers
GET /campaigns
List campaigns
Scope: campaigns:read.
| Parameter | In | Required | About |
|---|---|---|---|
limit | query | no | How many to return, 1 to 200 |
cursor | query | no | The next_cursor from the previous page |
Answer 200
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Campaign"
}
},
"next_cursor": {
"description": "Pass as cursor (or since, for events) to get the next page; null at the end",
"type": [
"string",
"null"
]
}
},
"required": [
"data",
"next_cursor"
],
"additionalProperties": false
}GET /campaigns/{id}
Get a campaign with its counts
Scope: campaigns:read.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Answer 200
GET /offers
List offers
Scope: offers:read.
| Parameter | In | Required | About |
|---|---|---|---|
limit | query | no | How many to return, 1 to 200 |
cursor | query | no | The next_cursor from the previous page |
Answer 200
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Offer"
}
},
"next_cursor": {
"description": "Pass as cursor (or since, for events) to get the next page; null at the end",
"type": [
"string",
"null"
]
}
},
"required": [
"data",
"next_cursor"
],
"additionalProperties": false
}GET /offers/{id}
Get an offer
Scope: offers:read.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Answer 200
GET /leads
List leads from offers
Scope: offers:read.
| Parameter | In | Required | About |
|---|---|---|---|
limit | query | no | How many to return, 1 to 200 |
cursor | query | no | The next_cursor from the previous page |
offer_id | query | no | An id |
status | query | no | One of started, verified, signed, abandoned, discarded, converted_existing, awaiting_review, declined_by_business, review_expired |
created_since | query | no |
Answer 200
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Lead"
}
},
"next_cursor": {
"description": "Pass as cursor (or since, for events) to get the next page; null at the end",
"type": [
"string",
"null"
]
}
},
"required": [
"data",
"next_cursor"
],
"additionalProperties": false
}Clients
GET /clients
List clients
Newest first. Archived clients only with archived=true. Filter by a client field with field.<name>=<value> (values compare as text: true, 2, Single).
Scope: clients:read.
| Parameter | In | Required | About |
|---|---|---|---|
limit | query | no | How many to return, 1 to 200 |
cursor | query | no | The next_cursor from the previous page |
search | query | no | string |
external_id | query | no | string |
email | query | no | string |
archived | query | no | One of true, false |
has_open_proposal | query | no | One of true, false |
updated_since | query | no |
Answer 200
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Client"
}
},
"next_cursor": {
"description": "Pass as cursor (or since, for events) to get the next page; null at the end",
"type": [
"string",
"null"
]
}
},
"required": [
"data",
"next_cursor"
],
"additionalProperties": false
}POST /clients
Add a client
Checked like an import row: display_name, and an email or external_id. One email can belong to several clients (a person and their business, say), so an email already in use still makes a new client; email_shared_with lists the others.
Scope: clients:write.
| Parameter | In | Required | About |
|---|---|---|---|
Idempotency-Key | header | yes | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Body
{
"type": "object",
"properties": {
"external_id": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
]
},
"display_name": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"first_name": {
"anyOf": [
{
"type": "string",
"maxLength": 120
},
{
"type": "null"
}
]
},
"email": {
"anyOf": [
{
"type": "string",
"maxLength": 254
},
{
"type": "null"
}
]
},
"phone": {
"anyOf": [
{
"type": "string",
"maxLength": 60
},
{
"type": "null"
}
]
},
"type": {
"description": "individual (the default) or business: an entity, whose display_name is the business's name and whose contact signs for it",
"type": "string",
"enum": [
"individual",
"business"
]
},
"contact_name": {
"description": "A business's contact person, in full. Business clients only",
"anyOf": [
{
"type": "string",
"maxLength": 120
},
{
"type": "null"
}
]
},
"contact_title": {
"description": "The contact's title (Managing Member), prefilled when they sign. Business clients only",
"anyOf": [
{
"type": "string",
"maxLength": 80
},
{
"type": "null"
}
]
},
"representative": {
"description": "Someone else signs for this individual client (power of attorney, guardian, executor, or personal representative): name, email, optional phone, and capacity. Everything is sent to them and nothing to the client. null removes it. Refused on a business",
"anyOf": [
{
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"email": {
"type": "string"
},
"phone": {
"anyOf": [
{
"type": "string",
"maxLength": 40
},
{
"type": "null"
}
]
},
"capacity": {
"type": "string",
"enum": [
"power_of_attorney",
"guardian",
"executor",
"personal_representative"
]
}
},
"required": [
"name",
"email",
"capacity"
]
},
{
"type": "null"
}
]
},
"prior_price_cents": {
"anyOf": [
{
"type": "integer",
"minimum": 0,
"maximum": 100000000
},
{
"type": "null"
}
]
},
"fields": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": [
"string",
"number",
"boolean",
"null"
]
}
}
},
"additionalProperties": false
}Answer 201
GET /clients/{id}
Get a client
Scope: clients:read.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Answer 200
PATCH /clients/{id}
Change a client
Only what you send changes; null clears a value. Fields not sent keep their values, and hidden fields are never touched.
Scope: clients:write.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Idempotency-Key | header | no | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Body
{
"type": "object",
"properties": {
"external_id": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
]
},
"display_name": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"first_name": {
"anyOf": [
{
"type": "string",
"maxLength": 120
},
{
"type": "null"
}
]
},
"email": {
"anyOf": [
{
"type": "string",
"maxLength": 254
},
{
"type": "null"
}
]
},
"phone": {
"anyOf": [
{
"type": "string",
"maxLength": 60
},
{
"type": "null"
}
]
},
"type": {
"description": "individual (the default) or business: an entity, whose display_name is the business's name and whose contact signs for it",
"type": "string",
"enum": [
"individual",
"business"
]
},
"contact_name": {
"description": "A business's contact person, in full. Business clients only",
"anyOf": [
{
"type": "string",
"maxLength": 120
},
{
"type": "null"
}
]
},
"contact_title": {
"description": "The contact's title (Managing Member), prefilled when they sign. Business clients only",
"anyOf": [
{
"type": "string",
"maxLength": 80
},
{
"type": "null"
}
]
},
"representative": {
"description": "Someone else signs for this individual client (power of attorney, guardian, executor, or personal representative): name, email, optional phone, and capacity. Everything is sent to them and nothing to the client. null removes it. Refused on a business",
"anyOf": [
{
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"email": {
"type": "string"
},
"phone": {
"anyOf": [
{
"type": "string",
"maxLength": 40
},
{
"type": "null"
}
]
},
"capacity": {
"type": "string",
"enum": [
"power_of_attorney",
"guardian",
"executor",
"personal_representative"
]
}
},
"required": [
"name",
"email",
"capacity"
]
},
{
"type": "null"
}
]
},
"prior_price_cents": {
"anyOf": [
{
"type": "integer",
"minimum": 0,
"maximum": 100000000
},
{
"type": "null"
}
]
},
"fields": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": [
"string",
"number",
"boolean",
"null"
]
}
}
},
"additionalProperties": false
}Answer 200
POST /clients/{id}/signing
Set who must sign a client's proposals
The default for new proposals when the client has signers besides themselves (Multiple signers): all of them, or any one. 403 without Multiple signers on the plan.
Scope: clients:write.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Idempotency-Key | header | no | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Body
{
"type": "object",
"properties": {
"rule": {
"type": "string",
"enum": [
"all",
"any"
]
}
},
"required": [
"rule"
],
"additionalProperties": false
}Answer 200
POST /clients/{id}/archive
Archive a client
Archived clients leave lists, campaigns, and pickers; their history stays.
Scope: clients:write.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Idempotency-Key | header | no | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Answer 200
POST /clients/{id}/restore
Restore an archived client
Scope: clients:write.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Idempotency-Key | header | no | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Answer 200
GET /clients/{id}/people
List a client's people
People copied on the client's new proposals: they get a view-only link and the signed copy, and can never choose or sign.
Scope: clients:read.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Answer 200
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ClientPerson"
}
},
"next_cursor": {
"description": "Pass as cursor (or since, for events) to get the next page; null at the end",
"type": [
"string",
"null"
]
}
},
"required": [
"data",
"next_cursor"
],
"additionalProperties": false
}POST /clients/{id}/people
Copy someone on a client's proposals
client_asked must be true: the client asked you to share their proposals with this person, and it's recorded with the API key and the time. The client's own email is refused. role signer needs Multiple signers on the plan (400 validation otherwise).
Scope: clients:write.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Idempotency-Key | header | yes | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Body
{
"type": "object",
"properties": {
"name": {
"type": "string",
"maxLength": 120
},
"email": {
"type": "string",
"maxLength": 254
},
"phone": {
"anyOf": [
{
"type": "string",
"maxLength": 40
},
{
"type": "null"
}
]
},
"relationship": {
"type": "string",
"enum": [
"spouse",
"family",
"assistant",
"business_partner",
"other"
]
},
"title": {
"description": "Their title at the business (Member, Partner); used only on a business client",
"anyOf": [
{
"type": "string",
"maxLength": 80
},
{
"type": "null"
}
]
},
"role": {
"description": "copied (the default), or signer where the business has Multiple signers",
"type": "string",
"enum": [
"copied",
"signer"
]
},
"client_asked": {
"description": "The client asked you to share their proposal with this person; required to add someone or change their email",
"type": "boolean"
}
},
"required": [
"name",
"email",
"relationship"
],
"additionalProperties": false
}Answer 201
PATCH /clients/{id}/people/{personId}
Change one of a client's people
Only what you send changes. A new email needs client_asked: true again. Proposals already sent keep who they were sent to.
Scope: clients:write.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
personId | path | yes | An id |
Idempotency-Key | header | no | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Body
{
"type": "object",
"properties": {
"name": {
"type": "string",
"maxLength": 120
},
"email": {
"type": "string",
"maxLength": 254
},
"phone": {
"anyOf": [
{
"type": "string",
"maxLength": 40
},
{
"type": "null"
}
]
},
"relationship": {
"type": "string",
"enum": [
"spouse",
"family",
"assistant",
"business_partner",
"other"
]
},
"title": {
"description": "Their title at the business (Member, Partner); used only on a business client",
"anyOf": [
{
"type": "string",
"maxLength": 80
},
{
"type": "null"
}
]
},
"role": {
"description": "copied (the default), or signer where the business has Multiple signers",
"type": "string",
"enum": [
"copied",
"signer"
]
},
"client_asked": {
"description": "The client asked you to share their proposal with this person; required to add someone or change their email",
"type": "boolean"
}
},
"additionalProperties": false
}Answer 200
DELETE /clients/{id}/people/{personId}
Stop copying someone on a client's proposals
Proposals already sent keep who they were sent to.
Scope: clients:write.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
personId | path | yes | An id |
Idempotency-Key | header | no | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Answer 200
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"deleted": {
"type": "boolean",
"const": true
}
},
"required": [
"id",
"deleted"
],
"additionalProperties": false
}POST /clients/batch
Import clients as JSON rows
{ rows: [ { external_id, display_name, email, first_name, phone, prior_price, client_type, business_name, contact_name, contact_title, <field>: value } ] }, 1 to 5,000 rows. prior_price is in major units (350.00), like a CSV. client_type is Individual or Business; a row with a business_name is a business named for it, and its display_name is the contact when contact_name is empty. A column a row leaves out keeps the client's value. A column no client field takes is 422 unknown_columns.
Scope: clients:write.
| Parameter | In | Required | About |
|---|---|---|---|
Idempotency-Key | header | no | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Body
{}Answer 200
POST /clients/import
Import clients from a CSV file
text/csv (text/plain and application/octet-stream are read as CSV too), or multipart form data with a file field. The same columns as POST /clients/batch, business columns included. 1 to 5,000 data rows: 413 too_many_rows past that. A column no client field takes is 422 unknown_columns.
Scope: clients:write.
| Parameter | In | Required | About |
|---|---|---|---|
Idempotency-Key | header | no | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Body
text/csv: A CSV with a header row
multipart/form-data: A CSV with a header row
Answer 200
Catalog
GET /catalog
List catalog items
Active items unless status says otherwise. Prices are minor units; unit_cents is null for no price yet.
Scope: catalog:read.
| Parameter | In | Required | About |
|---|---|---|---|
limit | query | no | How many to return, 1 to 200 |
cursor | query | no | The next_cursor from the previous page |
status | query | no | One of active, archived, all |
Answer 200
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CatalogItem"
}
},
"next_cursor": {
"description": "Pass as cursor (or since, for events) to get the next page; null at the end",
"type": [
"string",
"null"
]
}
},
"required": [
"data",
"next_cursor"
],
"additionalProperties": false
}POST /catalog
Add a catalog item
A single item has min_qty and max_qty 1; a counted one (per location, per return) sets a range and a unit_label. A rate billed as used sets billed_as_used and a unit_label (per form): it has no quantity and is never in a total. A unit_cents other than null needs the catalog:prices scope. Changing the catalog never changes proposals already made.
Scope: catalog:write.
| Parameter | In | Required | About |
|---|---|---|---|
Idempotency-Key | header | yes | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Body
{
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"category": {
"default": "",
"type": "string",
"maxLength": 60
},
"description": {
"default": "",
"type": "string",
"maxLength": 500
},
"includes": {
"default": [],
"maxItems": 20,
"type": "array",
"items": {
"type": "string",
"minLength": 1,
"maxLength": 200
}
},
"unit_label": {
"default": "",
"type": "string",
"maxLength": 40
},
"unit_plural": {
"default": "",
"type": "string",
"maxLength": 40
},
"unit_cents": {
"default": null,
"anyOf": [
{
"type": "integer",
"minimum": 0,
"maximum": 100000000
},
{
"type": "null"
}
]
},
"billing": {
"default": "one_time",
"type": "string",
"enum": [
"one_time",
"yearly",
"semiannual",
"quarterly",
"monthly",
"weekly"
]
},
"min_qty": {
"default": 1,
"type": "integer",
"minimum": 0,
"maximum": 999
},
"max_qty": {
"default": 1,
"type": "integer",
"minimum": 1,
"maximum": 999
},
"billed_as_used": {
"default": false,
"type": "boolean"
}
},
"required": [
"name"
],
"additionalProperties": false
}Answer 201
GET /catalog/{id}
Get a catalog item
Scope: catalog:read.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Answer 200
PATCH /catalog/{id}
Change a catalog item
Only what you send changes. An archived item must be restored first. Changing unit_cents needs the catalog:prices scope; a price change is logged with the old and new price, and live offers price from the catalog, so they use the new price at once.
Scope: catalog:write.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Idempotency-Key | header | no | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Body
{
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"category": {
"type": "string",
"maxLength": 60
},
"description": {
"type": "string",
"maxLength": 500
},
"includes": {
"maxItems": 20,
"type": "array",
"items": {
"type": "string",
"minLength": 1,
"maxLength": 200
}
},
"unit_label": {
"type": "string",
"maxLength": 40
},
"unit_plural": {
"type": "string",
"maxLength": 40
},
"unit_cents": {
"anyOf": [
{
"type": "integer",
"minimum": 0,
"maximum": 100000000
},
{
"type": "null"
}
]
},
"billing": {
"type": "string",
"enum": [
"one_time",
"yearly",
"semiannual",
"quarterly",
"monthly",
"weekly"
]
},
"min_qty": {
"type": "integer",
"minimum": 0,
"maximum": 999
},
"max_qty": {
"type": "integer",
"minimum": 1,
"maximum": 999
},
"billed_as_used": {
"type": "boolean"
}
},
"additionalProperties": false
}Answer 200
POST /catalog/{id}/archive
Archive a catalog item
It leaves pickers; proposals and presets that hold it keep their copy.
Scope: catalog:write.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Idempotency-Key | header | no | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Answer 200
POST /catalog/{id}/restore
Restore a catalog item
Scope: catalog:write.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Idempotency-Key | header | no | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Answer 200
Proposals
GET /proposals
List proposals
Newest first. Without status, everything that went out (no drafts); status=draft lists drafts made in the builder or the API. since is kept as another name for updated_since.
Scope: proposals:read.
| Parameter | In | Required | About |
|---|---|---|---|
limit | query | no | How many to return, 1 to 200 |
cursor | query | no | The next_cursor from the previous page |
status | query | no | One of draft, sent, viewed, signed, declined, expired, revoked, superseded |
handoff | query | no | One of pending, confirmed, failed |
client_id | query | no | An id |
campaign_id | query | no | An id |
offer_id | query | no | An id |
template_id | query | no | An id |
created_since | query | no | |
updated_since | query | no | |
signed_since | query | no | |
since | query | no |
Answer 200
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Proposal"
}
},
"next_cursor": {
"description": "Pass as cursor (or since, for events) to get the next page; null at the end",
"type": [
"string",
"null"
]
}
},
"required": [
"data",
"next_cursor"
],
"additionalProperties": false
}POST /proposals
Make a draft proposal
For one client, from a preset (preset_id), from a build in the short form (build), or empty. template_id defaults to the business's default template. It starts with the client's copied people; copied_people replaces them for this proposal only. Nothing is sent: preview it, then send it.
Scope: proposals:write.
| Parameter | In | Required | About |
|---|---|---|---|
Idempotency-Key | header | yes | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Body
{
"type": "object",
"properties": {
"client_id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"preset_id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"template_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"note": {
"type": "string",
"maxLength": 2000
},
"period": {
"type": "object",
"properties": {
"key": {
"type": "string",
"minLength": 1,
"maxLength": 40
},
"label": {
"type": "string",
"minLength": 1,
"maxLength": 80
}
},
"required": [
"key",
"label"
],
"additionalProperties": false
},
"expiry_days": {
"type": "integer",
"minimum": 1,
"maximum": 365
},
"build": {
"type": "object",
"properties": {
"mode": {
"type": "string",
"enum": [
"fixed",
"choose"
]
},
"packages": {
"minItems": 1,
"maxItems": 8,
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 80
},
"badge": {
"default": null,
"anyOf": [
{
"type": "string",
"maxLength": 40
},
{
"type": "null"
}
]
},
"description": {
"default": "",
"type": "string",
"maxLength": 500
},
"items": {
"default": [],
"maxItems": 60,
"type": "array",
"items": {
"anyOf": [
{
"type": "object",
"properties": {
"catalog_item_id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"qty": {
"default": 1,
"type": "integer",
"minimum": 0,
"maximum": 999
},
"unit_cents": {
"type": "integer",
"minimum": 0,
"maximum": 100000000
},
"unit_label": {
"type": "string",
"maxLength": 40
},
"unit_plural": {
"type": "string",
"maxLength": 40
}
},
"required": [
"catalog_item_id"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"description": {
"default": "",
"type": "string",
"maxLength": 500
},
"includes": {
"default": [],
"maxItems": 20,
"type": "array",
"items": {
"type": "string",
"minLength": 1,
"maxLength": 200
}
},
"unit_label": {
"default": "",
"type": "string",
"maxLength": 40
},
"unit_plural": {
"type": "string",
"maxLength": 40
},
"unit_cents": {
"type": "integer",
"minimum": 0,
"maximum": 100000000
},
"qty": {
"default": 1,
"type": "integer",
"minimum": 0,
"maximum": 999
},
"billing": {
"default": "one_time",
"type": "string",
"enum": [
"one_time",
"yearly",
"semiannual",
"quarterly",
"monthly",
"weekly"
]
},
"billed_as_used": {
"default": false,
"type": "boolean"
}
},
"required": [
"name",
"unit_cents"
],
"additionalProperties": false
}
]
}
}
},
"required": [
"name"
],
"additionalProperties": false
}
},
"addons": {
"default": [],
"maxItems": 30,
"type": "array",
"items": {
"type": "object",
"properties": {
"catalog_item_id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"description": {
"type": "string",
"maxLength": 500
},
"unit_label": {
"type": "string",
"maxLength": 40
},
"unit_plural": {
"type": "string",
"maxLength": 40
},
"unit_cents": {
"type": "integer",
"minimum": 0,
"maximum": 100000000
},
"billing": {
"type": "string",
"enum": [
"one_time",
"yearly",
"semiannual",
"quarterly",
"monthly",
"weekly"
]
},
"billed_as_used": {
"type": "boolean"
},
"kind": {
"type": "string",
"enum": [
"toggle",
"quantity"
]
},
"min_qty": {
"default": 0,
"type": "integer",
"minimum": 0,
"maximum": 999
},
"max_qty": {
"type": "integer",
"minimum": 1,
"maximum": 999
},
"only_with": {
"default": null,
"anyOf": [
{
"maxItems": 8,
"type": "array",
"items": {
"type": "integer",
"minimum": 0,
"maximum": 7
}
},
{
"type": "null"
}
]
}
},
"required": [
"kind"
],
"additionalProperties": false
}
},
"discounts": {}
},
"required": [
"mode",
"packages"
],
"additionalProperties": false
},
"copied_people": {
"maxItems": 10,
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"maxLength": 120
},
"email": {
"type": "string",
"maxLength": 254
},
"phone": {
"anyOf": [
{
"type": "string",
"maxLength": 40
},
{
"type": "null"
}
]
},
"relationship": {
"type": "string",
"enum": [
"spouse",
"family",
"assistant",
"business_partner",
"other"
]
},
"title": {
"description": "Their title at the business (Member, Partner); used only on a business client",
"anyOf": [
{
"type": "string",
"maxLength": 80
},
{
"type": "null"
}
]
},
"role": {
"description": "copied (the default), or signer where the business has Multiple signers",
"type": "string",
"enum": [
"copied",
"signer"
]
},
"client_asked": {
"description": "The client asked you to share their proposal with this person; required to add someone or change their email",
"type": "boolean"
}
},
"required": [
"name",
"email",
"relationship"
],
"additionalProperties": false
}
},
"copied_signed_copy": {
"type": "boolean"
},
"signing": {
"anyOf": [
{
"type": "object",
"properties": {
"rule": {
"type": "string",
"enum": [
"all",
"any"
]
},
"order": {
"default": "any",
"type": "string",
"enum": [
"any",
"in_order"
]
}
},
"required": [
"rule"
]
},
{
"type": "null"
}
]
}
},
"required": [
"client_id"
],
"additionalProperties": false
}Answer 201
GET /proposals/{id}
Get a proposal
With copied_people: everyone copied on it, whether their view-only link was emailed, and when they last looked.
Scope: proposals:read.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Answer 200
PATCH /proposals/{id}
Change a draft
Any change to the document throws away the preview; changing only copied_people or copied_signed_copy keeps it. A build sent here replaces the draft's packages and add-ons. 409 invalid_state once it's sent.
Scope: proposals:write.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Idempotency-Key | header | no | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Body
{
"type": "object",
"properties": {
"template_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"note": {
"type": "string",
"maxLength": 2000
},
"period": {
"type": "object",
"properties": {
"key": {
"type": "string",
"minLength": 1,
"maxLength": 40
},
"label": {
"type": "string",
"minLength": 1,
"maxLength": 80
}
},
"required": [
"key",
"label"
],
"additionalProperties": false
},
"expiry_days": {
"type": "integer",
"minimum": 1,
"maximum": 365
},
"build": {
"type": "object",
"properties": {
"mode": {
"type": "string",
"enum": [
"fixed",
"choose"
]
},
"packages": {
"minItems": 1,
"maxItems": 8,
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 80
},
"badge": {
"default": null,
"anyOf": [
{
"type": "string",
"maxLength": 40
},
{
"type": "null"
}
]
},
"description": {
"default": "",
"type": "string",
"maxLength": 500
},
"items": {
"default": [],
"maxItems": 60,
"type": "array",
"items": {
"anyOf": [
{
"type": "object",
"properties": {
"catalog_item_id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"qty": {
"default": 1,
"type": "integer",
"minimum": 0,
"maximum": 999
},
"unit_cents": {
"type": "integer",
"minimum": 0,
"maximum": 100000000
},
"unit_label": {
"type": "string",
"maxLength": 40
},
"unit_plural": {
"type": "string",
"maxLength": 40
}
},
"required": [
"catalog_item_id"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"description": {
"default": "",
"type": "string",
"maxLength": 500
},
"includes": {
"default": [],
"maxItems": 20,
"type": "array",
"items": {
"type": "string",
"minLength": 1,
"maxLength": 200
}
},
"unit_label": {
"default": "",
"type": "string",
"maxLength": 40
},
"unit_plural": {
"type": "string",
"maxLength": 40
},
"unit_cents": {
"type": "integer",
"minimum": 0,
"maximum": 100000000
},
"qty": {
"default": 1,
"type": "integer",
"minimum": 0,
"maximum": 999
},
"billing": {
"default": "one_time",
"type": "string",
"enum": [
"one_time",
"yearly",
"semiannual",
"quarterly",
"monthly",
"weekly"
]
},
"billed_as_used": {
"default": false,
"type": "boolean"
}
},
"required": [
"name",
"unit_cents"
],
"additionalProperties": false
}
]
}
}
},
"required": [
"name"
],
"additionalProperties": false
}
},
"addons": {
"default": [],
"maxItems": 30,
"type": "array",
"items": {
"type": "object",
"properties": {
"catalog_item_id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"description": {
"type": "string",
"maxLength": 500
},
"unit_label": {
"type": "string",
"maxLength": 40
},
"unit_plural": {
"type": "string",
"maxLength": 40
},
"unit_cents": {
"type": "integer",
"minimum": 0,
"maximum": 100000000
},
"billing": {
"type": "string",
"enum": [
"one_time",
"yearly",
"semiannual",
"quarterly",
"monthly",
"weekly"
]
},
"billed_as_used": {
"type": "boolean"
},
"kind": {
"type": "string",
"enum": [
"toggle",
"quantity"
]
},
"min_qty": {
"default": 0,
"type": "integer",
"minimum": 0,
"maximum": 999
},
"max_qty": {
"type": "integer",
"minimum": 1,
"maximum": 999
},
"only_with": {
"default": null,
"anyOf": [
{
"maxItems": 8,
"type": "array",
"items": {
"type": "integer",
"minimum": 0,
"maximum": 7
}
},
{
"type": "null"
}
]
}
},
"required": [
"kind"
],
"additionalProperties": false
}
},
"discounts": {}
},
"required": [
"mode",
"packages"
],
"additionalProperties": false
},
"copied_people": {
"maxItems": 10,
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"maxLength": 120
},
"email": {
"type": "string",
"maxLength": 254
},
"phone": {
"anyOf": [
{
"type": "string",
"maxLength": 40
},
{
"type": "null"
}
]
},
"relationship": {
"type": "string",
"enum": [
"spouse",
"family",
"assistant",
"business_partner",
"other"
]
},
"title": {
"description": "Their title at the business (Member, Partner); used only on a business client",
"anyOf": [
{
"type": "string",
"maxLength": 80
},
{
"type": "null"
}
]
},
"role": {
"description": "copied (the default), or signer where the business has Multiple signers",
"type": "string",
"enum": [
"copied",
"signer"
]
},
"client_asked": {
"description": "The client asked you to share their proposal with this person; required to add someone or change their email",
"type": "boolean"
}
},
"required": [
"name",
"email",
"relationship"
],
"additionalProperties": false
}
},
"copied_signed_copy": {
"type": "boolean"
},
"signing": {
"anyOf": [
{
"type": "object",
"properties": {
"rule": {
"type": "string",
"enum": [
"all",
"any"
]
},
"order": {
"default": "any",
"type": "string",
"enum": [
"any",
"in_order"
]
}
},
"required": [
"rule"
]
},
{
"type": "null"
}
]
}
},
"additionalProperties": false
}Answer 200
POST /proposals/{id}/copied/{personId}/resend
Send a copied person their copy again
Emails them their view-only link again: the same link while the proposal is open, otherwise a new one (their earlier link stops). After Remove access it gives them a new link. Needs an email sender; refused while email is paused, as other sends are.
Scope: proposals:send.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
personId | path | yes | An id |
Idempotency-Key | header | yes | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Answer 200
POST /proposals/{id}/copied/{personId}/remove-access
Remove a copied person's access
Their link says it's no longer active, for good, and they get no signed copy or withdrawn notice. Send their copy again to give them a new link.
Scope: proposals:write.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
personId | path | yes | An id |
Idempotency-Key | header | no | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Answer 200
POST /proposals/{id}/preview
Preview a draft
Freezes exactly what the client would get and fixes its respond-by date. Send needs this preview_sha256. A preview goes stale at the end of the business's day or after 24 hours.
Scope: proposals:write.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Idempotency-Key | header | no | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Answer 200
GET /proposals/{id}/preview/document
The previewed document
The rendered HTML of the stored preview, the same as the client will see.
Scope: proposals:read.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Answer 200
text/html
POST /proposals/{id}/send
Send a previewed draft
Needs the preview_sha256 from the preview: 409 not_previewed, preview_changed, or preview_stale otherwise. email: true emails the link (409 send_blocked while email is paused, as in the admin); false makes the link without emailing it. Uses a credit (402 out_of_credits when there's none); a revision is free, unless the version it replaces was withdrawn before the client opened it, which gave its credit back. The link is never in this answer: read it with GET /proposals/{id}/link.
Scope: proposals:send.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Idempotency-Key | header | yes | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Body
{
"type": "object",
"properties": {
"preview_sha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"email": {
"type": "boolean"
},
"email_copied": {
"type": "boolean"
}
},
"required": [
"preview_sha256",
"email"
],
"additionalProperties": false
}Answer 200
POST /proposals/{id}/withdraw
Withdraw a sent proposal
Its link then says it was withdrawn. email_client emails the client the withdrawn notice when the business has a sender. Withdrawn before it was opened, its credit comes back.
Scope: proposals:send.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Idempotency-Key | header | no | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Body
{
"type": "object",
"properties": {
"email_client": {
"type": "boolean"
},
"note": {
"anyOf": [
{
"type": "string",
"maxLength": 1000
},
{
"type": "null"
}
]
}
},
"required": [
"email_client"
],
"additionalProperties": false
}Answer 200
POST /proposals/{id}/resend
Resend a sent proposal's link to the client
The admin's Resend: the client gets a new link and their earlier links stop working. An expired proposal reopens only within 30 days of its deadline: it's extended first (proposal.deadline_extended, with the reason "Sent a new link") to expiry_days from today, and the date the document printed doesn't change. After 30 days, or for a withdrawn one, it's refused (409 invalid_state); revise it to send it again. emailed is false when the business has no email sender (proposal.sent tells your automation). The link is never in this answer.
Scope: proposals:send.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Idempotency-Key | header | yes | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Answer 200
POST /proposals/{id}/extend
Extend a sent proposal's deadline
More time on the same proposal: the link the client has keeps working, and the document keeps the respond-by date it printed. Open proposals any time before the deadline; an expired one within 30 days of its deadline, which reopens it. notify_client (default true) emails a second link with the new date. Its expires_at is then the new deadline, with original_expires_at the printed date. 409 invalid_state for a draft, a closed proposal, one that ended more than 30 days ago, or one in a walkthrough (extend the walkthrough in EngageCycle); 422 validation for the date. Writes proposal.deadline_extended.
Scope: proposals:send.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Idempotency-Key | header | yes | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Body
{
"type": "object",
"properties": {
"expires_on": {
"type": "string",
"maxLength": 40,
"description": "The new deadline, a date in the business's time zone (YYYY-MM-DD). It ends at the end of that day. Later than the current deadline, not in the past, and at most 180 days from today."
},
"reason": {
"description": "Why, for the business's own team: in the activity and the event, never shown to the client",
"anyOf": [
{
"type": "string",
"maxLength": 500
},
{
"type": "null"
}
]
},
"notify_client": {
"description": "Email the client (and each signer whose turn it is) a second link with the new date; the link they have keeps working. Default true.",
"type": "boolean"
}
},
"required": [
"expires_on"
],
"additionalProperties": false
}Answer 200
POST /proposals/{id}/revise
Start a revision
A draft copied from what was sent (or the revision already started). Sending it replaces the old version, and the old link leads to it.
Scope: proposals:write.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Idempotency-Key | header | yes | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Answer 201
GET /proposals/{id}/link
The client's signing link
The link the client already has, while the proposal is open. Nothing new is made. Every read is in the activity log.
Scope: proposals:links.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Answer 200
GET /proposals/{id}/pdf
The signed PDF
With the certificate page. X-EngageCycle-Sha256 is the file's hash. 409 not_signed before it's signed, and pdf_not_ready while it's being made.
Scope: proposals:read.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Answer 200
application/pdf
Automation
POST /proposals/{id}/handoff
Record the handoff of a signed proposal
Your automation says it filed the signed proposal (confirmed) or couldn't (failed).
Scope: proposals:write.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Idempotency-Key | header | no | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Body
{
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"confirmed",
"failed"
]
},
"detail": {
"type": "string",
"maxLength": 2000
}
},
"required": [
"status"
],
"additionalProperties": false
}Answer 200
{
"type": "object",
"properties": {
"ok": {
"type": "boolean",
"const": true
},
"handoff": {
"type": "object",
"properties": {
"status": {
"type": "string"
},
"at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"detail": {
"type": [
"string",
"null"
]
}
},
"required": [
"status",
"at",
"detail"
],
"additionalProperties": false
}
},
"required": [
"ok",
"handoff"
],
"additionalProperties": false
}POST /proposals/{id}/booked
Record a booked call
Scope: proposals:write.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Idempotency-Key | header | no | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Body
{
"type": "object",
"properties": {
"provider": {
"type": "string",
"minLength": 1,
"maxLength": 40
},
"external_id": {
"type": "string",
"maxLength": 200
},
"starts_at": {},
"source": {
"default": "api",
"type": "string",
"maxLength": 40
}
},
"required": [
"provider"
]
}Answer 200
{
"type": "object",
"properties": {
"ok": {
"type": "boolean",
"const": true
},
"proposal_id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"booked": {
"type": "boolean",
"const": true
}
},
"required": [
"ok",
"proposal_id",
"booked"
],
"additionalProperties": false
}POST /bookings/match
Match a booking to an open proposal by email
404 no_open_proposal when the email has none, so bookings that aren't about a proposal can be ignored. When several clients use the email (a person and their business, say), each one's open proposal is booked.
Scope: proposals:write.
| Parameter | In | Required | About |
|---|---|---|---|
Idempotency-Key | header | no | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Body
{
"type": "object",
"properties": {
"provider": {
"type": "string",
"minLength": 1,
"maxLength": 40
},
"external_id": {
"type": "string",
"maxLength": 200
},
"starts_at": {},
"source": {
"default": "api",
"type": "string",
"maxLength": 40
},
"email": {
"type": "string",
"format": "email",
"pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
}
},
"required": [
"provider",
"email"
]
}Answer 200
{
"type": "object",
"properties": {
"ok": {
"type": "boolean",
"const": true
},
"proposal_id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
"description": "The newest open proposal booked"
},
"booked": {
"type": "boolean",
"const": true
},
"proposal_ids": {
"type": "array",
"items": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"description": "Every open proposal booked, newest first. One email can belong to several clients (a person and their business, say), and each one's open proposal is marked."
}
},
"required": [
"ok",
"proposal_id",
"booked",
"proposal_ids"
],
"additionalProperties": false
}Documents
GET /documents
List documents
Agreements and consents sent on their own, newest first (never a draft, never a proposal). 403 forbidden when Agreement and Consent aren't on the plan.
Scope: documents:read.
| Parameter | In | Required | About |
|---|---|---|---|
limit | query | no | How many to return, 1 to 200 |
cursor | query | no | The next_cursor from the previous page |
kind | query | no | One of agreement, consent |
status | query | no | One of sent, viewed, signed, declined, expired, revoked, superseded |
client_id | query | no | An id |
since | query | no | Changed since this time |
Answer 200
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Document"
}
},
"next_cursor": {
"description": "Pass as cursor (or since, for events) to get the next page; null at the end",
"type": [
"string",
"null"
]
}
},
"required": [
"data",
"next_cursor"
],
"additionalProperties": false
}GET /documents/{id}
Get a document
Its kind, template, status, client, signers (position and answer), and the signature once signed. A proposal's id is not found here.
Scope: documents:read.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Answer 200
GET /documents/{id}/pdf
The signed PDF
With the certificate page. X-EngageCycle-Sha256 is the file's hash. 409 not_signed or pdf_not_ready while there isn't one.
Scope: documents:read.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | An id |
Answer 200
application/pdf
Events
GET /events
List events
The same envelope as the webhook, oldest first, every event recorded (also those recorded while the webhook was off). Pass the last next_cursor as since to get only what's new; an event never appears before one that was written earlier and is still being committed, so polling misses nothing. type can repeat. Documents' events (document.*) come back only when named in type, with the documents:read scope. Links in payloads come back only with the proposals:links scope.
Scope: events:read.
| Parameter | In | Required | About |
|---|---|---|---|
type | query | no | Text, or repeat it for several |
proposal_id | query | no | An id |
since | query | no | string |
limit | query | no | integer |
Answer 200
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Event"
}
},
"next_cursor": {
"description": "Pass as cursor (or since, for events) to get the next page; null at the end",
"type": [
"string",
"null"
]
}
},
"required": [
"data",
"next_cursor"
],
"additionalProperties": false
}POST /events/{id}/redeliver
Send an event to your webhook again
Marks a delivered or failed event to be delivered again, with the same event id and a new signature. 409 webhook_off when the webhook isn't on.
Scope: events:write.
| Parameter | In | Required | About |
|---|---|---|---|
id | path | yes | string |
Idempotency-Key | header | no | Any unique string, up to 200 characters. Repeating the request with the same key within 24 hours returns the first answer instead of doing it again. |
Answer 200
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"type": {
"type": "string"
},
"delivery": {
"type": "string",
"const": "due"
}
},
"required": [
"id",
"type",
"delivery"
],
"additionalProperties": false
}Shapes
Error
{
"type": "object",
"properties": {
"error": {
"type": "object",
"properties": {
"code": {
"type": "string",
"description": "Stable code to branch on"
},
"message": {
"type": "string",
"description": "Words for a person"
},
"field": {
"description": "The input at fault, as a dotted path",
"type": "string"
},
"details": {
"type": "array",
"items": {
"type": "string"
}
},
"scope": {
"description": "missing_scope: the scope the key needs",
"type": "string"
},
"columns": {
"description": "unknown_columns: the columns",
"type": "array",
"items": {
"type": "string"
}
},
"request_id": {
"description": "internal_error: quote it to support",
"type": "string"
}
},
"required": [
"code",
"message"
],
"additionalProperties": {}
}
},
"required": [
"error"
],
"additionalProperties": false
}Me
{
"type": "object",
"properties": {
"tenant": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"slug": {
"type": "string"
},
"name": {
"type": "string"
},
"currency": {
"type": "string"
},
"timezone": {
"type": "string"
}
},
"required": [
"id",
"slug",
"name",
"currency",
"timezone"
],
"additionalProperties": false
},
"key": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"prefix": {
"type": "string"
},
"scopes": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"description": "null: full access (a legacy key)"
}
},
"required": [
"name",
"prefix",
"scopes"
],
"additionalProperties": false
}
},
"required": [
"tenant",
"key"
],
"additionalProperties": false
}Credits
{
"type": "object",
"properties": {
"tracked": {
"type": "boolean",
"description": "false before credits start for the business"
},
"plan": {
"anyOf": [
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"included_credits": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"year_start": {
"type": [
"string",
"null"
]
},
"year_end": {
"type": [
"string",
"null"
]
},
"overage_rule": {
"type": "string"
},
"overage_cap": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
]
}
},
"required": [
"name",
"included_credits",
"year_start",
"year_end",
"overage_rule",
"overage_cap"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"total": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"used": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"left": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"overage_used": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"overage_room": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"can_send": {
"type": "boolean"
}
},
"required": [
"tracked",
"plan",
"can_send"
],
"additionalProperties": false
}Template
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"slug": {
"type": "string"
},
"name": {
"type": "string"
},
"title": {
"type": "string"
},
"kind": {
"type": "string"
},
"version": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"default": {
"type": "boolean"
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
}
},
"required": [
"id",
"slug",
"name",
"title",
"kind",
"version",
"default",
"created_at"
],
"additionalProperties": false
}Preset
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"mode": {
"type": "string",
"enum": [
"fixed",
"choose"
]
},
"currency": {
"type": "string"
},
"packages": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"total_cents": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
],
"description": "Kept for compatibility: one-time plus yearly. Use totals, which also carries amounts billed every six months, quarterly, or weekly."
},
"monthly_cents": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
],
"description": "Kept for compatibility: the monthly amount. Use totals."
},
"totals": {
"anyOf": [
{
"$ref": "#/components/schemas/BillingTotals"
},
{
"type": "null"
}
],
"description": "null while an item has no price"
}
},
"required": [
"id",
"name",
"total_cents",
"monthly_cents",
"totals"
],
"additionalProperties": false
}
},
"addons": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"unit_cents": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
]
}
},
"required": [
"id",
"name",
"unit_cents"
],
"additionalProperties": false
}
},
"unpriced": {
"type": "array",
"items": {
"type": "string"
}
},
"archived": {
"type": "boolean"
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"updated_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
}
},
"required": [
"id",
"name",
"description",
"mode",
"currency",
"packages",
"addons",
"unpriced",
"archived",
"created_at",
"updated_at"
],
"additionalProperties": false
}BillingTotals
{
"type": "array",
"items": {
"type": "object",
"properties": {
"billing": {
"type": "string",
"enum": [
"one_time",
"yearly",
"semiannual",
"quarterly",
"monthly",
"weekly"
]
},
"cents": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"billing",
"cents"
],
"additionalProperties": false
},
"description": "Each billing frequency's own total, in order: one_time, yearly, semiannual, quarterly, monthly, weekly. Only frequencies with an amount are listed; with none, a single one_time total of 0."
}Campaign
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"name": {
"type": "string"
},
"kind": {
"type": "string"
},
"status": {
"type": "string"
},
"template_id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"batch_size": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"batch_every_minutes": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"next_batch_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"held": {
"type": "boolean",
"description": "Paused by EngageCycle support"
},
"counts": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"description": "Proposals by status"
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"updated_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
}
},
"required": [
"id",
"name",
"kind",
"status",
"template_id",
"batch_size",
"batch_every_minutes",
"next_batch_at",
"held",
"counts",
"created_at",
"updated_at"
],
"additionalProperties": false
}Offer
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"name": {
"type": "string"
},
"slug": {
"type": "string"
},
"status": {
"type": "string"
},
"availability": {
"type": "string"
},
"url": {
"type": "string"
},
"opens_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"closes_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"template_id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"funnel": {
"type": "object",
"properties": {
"visits": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"started": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"verified": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"signed": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"abandoned": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"visits",
"started",
"verified",
"signed",
"abandoned"
],
"additionalProperties": false
},
"archived": {
"type": "boolean"
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"updated_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
}
},
"required": [
"id",
"name",
"slug",
"status",
"availability",
"url",
"opens_at",
"closes_at",
"template_id",
"funnel",
"archived",
"created_at",
"updated_at"
],
"additionalProperties": false
}Lead
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"offer_id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"status": {
"type": "string",
"description": "started, verified, signed, abandoned, discarded, converted_existing, or, on an offer that holds requests for review, awaiting_review, declined_by_business, or review_expired"
},
"outcome": {
"type": [
"string",
"null"
]
},
"email": {
"type": "string"
},
"name": {
"type": [
"string",
"null"
]
},
"phone": {
"type": [
"string",
"null"
]
},
"answers": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {},
"description": "Keyed by question id"
},
"utm": {
"anyOf": [
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "string"
}
},
{
"type": "null"
}
]
},
"marketing_consent": {
"type": "boolean"
},
"client_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"proposal_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"verified_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"contacted_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"last_activity_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
}
},
"required": [
"id",
"offer_id",
"status",
"outcome",
"email",
"name",
"phone",
"answers",
"utm",
"marketing_consent",
"client_id",
"proposal_id",
"verified_at",
"contacted_at",
"last_activity_at",
"created_at"
],
"additionalProperties": false
}Client
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"external_id": {
"type": [
"string",
"null"
]
},
"display_name": {
"type": "string"
},
"first_name": {
"type": [
"string",
"null"
]
},
"email": {
"type": [
"string",
"null"
]
},
"phone": {
"type": [
"string",
"null"
]
},
"type": {
"type": "string",
"enum": [
"individual",
"business"
],
"description": "individual (a person, and every client nobody marked) or business (an entity)"
},
"contact_name": {
"description": "A business's contact person, in full; null for an individual",
"type": [
"string",
"null"
]
},
"contact_title": {
"description": "The contact's title (Managing Member), prefilled when they sign; business only",
"type": [
"string",
"null"
]
},
"representative": {
"description": "Someone else signs for this individual client: everything is sent to them, nothing to the client. Absent when the client signs",
"type": "object",
"properties": {
"name": {
"type": "string"
},
"email": {
"type": "string"
},
"phone": {
"type": [
"string",
"null"
]
},
"capacity": {
"type": "string",
"enum": [
"power_of_attorney",
"guardian",
"executor",
"personal_representative"
]
}
},
"required": [
"name",
"email",
"phone",
"capacity"
],
"additionalProperties": false
},
"prior_price_cents": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
]
},
"currency": {
"type": "string"
},
"fields": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"is_new": {
"type": "boolean"
},
"source": {
"type": "string"
},
"archived": {
"type": "boolean"
},
"archived_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"signing_rule": {
"anyOf": [
{
"type": "string",
"enum": [
"all",
"any"
]
},
{
"type": "null"
}
],
"description": "Who must sign this client's proposals by default (Multiple signers); null is all"
},
"has_open_proposal": {
"type": "boolean"
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"updated_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
}
},
"required": [
"id",
"external_id",
"display_name",
"first_name",
"email",
"phone",
"type",
"contact_name",
"contact_title",
"prior_price_cents",
"currency",
"fields",
"is_new",
"source",
"archived",
"archived_at",
"signing_rule",
"has_open_proposal",
"created_at",
"updated_at"
],
"additionalProperties": false
}CreatedClient
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"external_id": {
"type": [
"string",
"null"
]
},
"display_name": {
"type": "string"
},
"first_name": {
"type": [
"string",
"null"
]
},
"email": {
"type": [
"string",
"null"
]
},
"phone": {
"type": [
"string",
"null"
]
},
"type": {
"type": "string",
"enum": [
"individual",
"business"
],
"description": "individual (a person, and every client nobody marked) or business (an entity)"
},
"contact_name": {
"description": "A business's contact person, in full; null for an individual",
"type": [
"string",
"null"
]
},
"contact_title": {
"description": "The contact's title (Managing Member), prefilled when they sign; business only",
"type": [
"string",
"null"
]
},
"representative": {
"description": "Someone else signs for this individual client: everything is sent to them, nothing to the client. Absent when the client signs",
"type": "object",
"properties": {
"name": {
"type": "string"
},
"email": {
"type": "string"
},
"phone": {
"type": [
"string",
"null"
]
},
"capacity": {
"type": "string",
"enum": [
"power_of_attorney",
"guardian",
"executor",
"personal_representative"
]
}
},
"required": [
"name",
"email",
"phone",
"capacity"
],
"additionalProperties": false
},
"prior_price_cents": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
]
},
"currency": {
"type": "string"
},
"fields": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"is_new": {
"type": "boolean"
},
"source": {
"type": "string"
},
"archived": {
"type": "boolean"
},
"archived_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"signing_rule": {
"anyOf": [
{
"type": "string",
"enum": [
"all",
"any"
]
},
{
"type": "null"
}
],
"description": "Who must sign this client's proposals by default (Multiple signers); null is all"
},
"has_open_proposal": {
"type": "boolean"
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"updated_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"email_shared_with": {
"type": "array",
"items": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"description": "Other clients that already use this email, by id, oldest first; empty when none. One email can belong to several clients, such as a person and their business."
}
},
"required": [
"id",
"external_id",
"display_name",
"first_name",
"email",
"phone",
"type",
"contact_name",
"contact_title",
"prior_price_cents",
"currency",
"fields",
"is_new",
"source",
"archived",
"archived_at",
"signing_rule",
"has_open_proposal",
"created_at",
"updated_at",
"email_shared_with"
],
"additionalProperties": false
}ClientPerson
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"client_id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"name": {
"type": "string"
},
"email": {
"type": "string"
},
"phone": {
"type": [
"string",
"null"
]
},
"title": {
"description": "Their title at the business (Member, Partner); used only on a business client",
"type": [
"string",
"null"
]
},
"relationship": {
"type": "string",
"enum": [
"spouse",
"family",
"assistant",
"business_partner",
"other"
]
},
"role": {
"type": "string",
"enum": [
"copied",
"signer"
]
},
"client_asked_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
"description": "When someone confirmed the client asked to share with them"
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"updated_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
}
},
"required": [
"id",
"client_id",
"name",
"email",
"phone",
"title",
"relationship",
"role",
"client_asked_at",
"created_at",
"updated_at"
],
"additionalProperties": false
}ImportSummary
{
"type": "object",
"properties": {
"ok": {
"type": "boolean"
},
"summary": {
"type": "object",
"properties": {
"received": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"imported": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"created": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"updated": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"rejected": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"received",
"imported",
"created",
"updated",
"rejected"
],
"additionalProperties": false
},
"errors": {
"type": "array",
"items": {}
}
},
"required": [
"ok",
"summary",
"errors"
],
"additionalProperties": {}
}CatalogItem
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"name": {
"type": "string"
},
"category": {
"description": "null: no category",
"type": [
"string",
"null"
]
},
"description": {
"type": "string"
},
"includes": {
"type": "array",
"items": {
"type": "string"
}
},
"unit_label": {
"description": "null: no unit",
"type": [
"string",
"null"
]
},
"unit_plural": {
"description": "null: the unit plus s",
"type": [
"string",
"null"
]
},
"unit_cents": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
],
"description": "null: no price yet"
},
"price_set": {
"type": "boolean"
},
"price": {
"type": [
"string",
"null"
]
},
"currency": {
"type": "string"
},
"billing": {
"type": "string",
"enum": [
"one_time",
"yearly",
"semiannual",
"quarterly",
"monthly",
"weekly"
]
},
"min_qty": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"max_qty": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"billed_as_used": {
"type": "boolean",
"description": "A rate per unit_label, with no quantity; never in a total"
},
"status": {
"type": "string",
"enum": [
"active",
"archived"
]
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"updated_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
}
},
"required": [
"id",
"name",
"category",
"description",
"includes",
"unit_label",
"unit_plural",
"unit_cents",
"price_set",
"price",
"currency",
"billing",
"min_qty",
"max_qty",
"billed_as_used",
"status",
"created_at",
"updated_at"
],
"additionalProperties": false
}Proposal
{
"type": "object",
"properties": {
"proposal": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"version": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"status": {
"type": "string",
"enum": [
"draft",
"sent",
"viewed",
"signed",
"declined",
"expired",
"revoked",
"superseded"
]
},
"client_id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"template_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"campaign_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"offer_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"packet_id": {
"description": "The walkthrough it was sent in; present only when it's part of a walkthrough",
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"build": {
"description": "Drafts only",
"anyOf": [
{
"$ref": "#/components/schemas/PricedBuild"
},
{
"type": "null"
}
]
},
"preview": {
"description": "Drafts only",
"anyOf": [
{
"type": "object",
"properties": {
"preview_sha256": {
"type": "string"
},
"previewed_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"fresh_until": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"fresh": {
"type": "boolean"
},
"expires_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
}
},
"required": [
"preview_sha256",
"previewed_at",
"fresh_until",
"fresh",
"expires_at"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"updated_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
}
},
"required": [
"id",
"version",
"status",
"client_id",
"template_id",
"campaign_id",
"offer_id",
"created_at",
"updated_at"
],
"additionalProperties": {}
},
"signature": {
"anyOf": [
{
"type": "object",
"properties": {
"signed_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"typed_name": {
"type": "string"
},
"signer_title": {
"description": "Signed for a business client: the signer's title; absent otherwise",
"type": "string"
},
"signer_capacity": {
"description": "Signed by a represented client's representative: how they signed for the client; absent otherwise",
"type": "string",
"enum": [
"power_of_attorney",
"guardian",
"executor",
"personal_representative"
]
},
"on_behalf_of": {
"description": "Signed for a business client, or by a represented client's representative: who for; absent otherwise",
"type": "string"
},
"total_cents": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991,
"description": "Kept for compatibility: one-time plus yearly. Use totals, which also carries amounts billed every six months, quarterly, or weekly."
},
"monthly_cents": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991,
"description": "Kept for compatibility: the monthly amount. Use totals."
},
"totals": {
"description": "What the client agreed to pay: net of any discounts",
"$ref": "#/components/schemas/BillingTotals"
},
"currency": {
"type": "string"
},
"discounts": {
"description": "Discount lines that came off, each with its kind; present only when one did (as in the webhook events, /api/docs/webhooks)",
"type": "array",
"items": {
"type": "object",
"properties": {
"kind": {
"type": "string"
},
"label": {
"type": "string"
},
"amount_cents": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"kind",
"label",
"amount_cents"
],
"additionalProperties": {}
}
},
"listed_totals": {
"description": "The totals before discounts; present only with discounts",
"$ref": "#/components/schemas/BillingTotals"
},
"pdf": {
"type": "object",
"properties": {
"url": {
"type": [
"string",
"null"
]
},
"sha256": {
"type": [
"string",
"null"
]
},
"ready": {
"type": "boolean"
}
},
"required": [
"url",
"sha256",
"ready"
],
"additionalProperties": false
}
},
"required": [
"signed_at",
"typed_name",
"total_cents",
"monthly_cents",
"totals",
"currency",
"pdf"
],
"additionalProperties": {}
},
{
"type": "null"
}
]
}
},
"required": [
"proposal",
"signature"
],
"additionalProperties": false,
"description": "A sent proposal carries the webhook's proposal block (/api/docs/webhooks) plus these ids and times; a draft carries its build and preview instead."
}PricedBuild
{
"type": "object",
"properties": {
"mode": {
"type": "string",
"enum": [
"fixed",
"choose"
]
},
"period": {
"type": "object",
"properties": {
"key": {
"type": "string"
},
"label": {
"type": "string"
}
},
"required": [
"key",
"label"
],
"additionalProperties": false
},
"expiry_days": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"note": {
"type": "string"
},
"currency": {
"type": "string"
},
"packages": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"badge": {
"type": [
"string",
"null"
]
},
"description": {
"type": "string"
},
"total_cents": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
],
"description": "Kept for compatibility: one-time plus yearly. Use totals, which also carries amounts billed every six months, quarterly, or weekly."
},
"monthly_cents": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
],
"description": "Kept for compatibility: the monthly amount. Use totals."
},
"totals": {
"anyOf": [
{
"$ref": "#/components/schemas/BillingTotals"
},
{
"type": "null"
}
],
"description": "null while an item has no price"
},
"net_totals": {
"description": "This package alone, net of the discount lines; present only with discounts",
"$ref": "#/components/schemas/BillingTotals"
},
"lines": {
"type": "array",
"items": {
"type": "object",
"properties": {
"catalog_item_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"name": {
"type": "string"
},
"qty": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"unit_cents": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
]
},
"amount_cents": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
]
},
"billing": {
"type": "string",
"enum": [
"one_time",
"yearly",
"semiannual",
"quarterly",
"monthly",
"weekly"
]
},
"billed_as_used": {
"type": "boolean",
"description": "A rate: unit_cents per unit_label, qty and amount 0, in no total"
},
"unit_label": {
"type": "string"
}
},
"required": [
"catalog_item_id",
"name",
"qty",
"unit_cents",
"amount_cents",
"billing",
"billed_as_used",
"unit_label"
],
"additionalProperties": false
}
}
},
"required": [
"id",
"name",
"badge",
"description",
"total_cents",
"monthly_cents",
"totals",
"lines"
],
"additionalProperties": false
}
},
"addons": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"unit_cents": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
]
}
},
"required": [
"id",
"name",
"unit_cents"
],
"additionalProperties": {}
}
},
"discounts": {
"description": "Discount lines, read-only over the API: fixed amounts taken off whatever the client chooses, each in one frequency. Absent when there are none.",
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"discount_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
],
"description": "null: a one-off typed in the builder"
},
"kind": {
"type": "string",
"const": "per_client"
},
"label": {
"type": "string"
},
"amount_cents": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991,
"description": "Positive: this much is taken off"
},
"billing": {
"type": "string",
"enum": [
"one_time",
"yearly",
"semiannual",
"quarterly",
"monthly",
"weekly"
]
}
},
"required": [
"id",
"discount_id",
"kind",
"label",
"amount_cents",
"billing"
],
"additionalProperties": false
}
},
"unpriced": {
"type": "array",
"items": {
"type": "string"
},
"description": "Items with no price yet; preview refuses while any"
},
"no_unit": {
"type": "array",
"items": {
"type": "string"
},
"description": "Rates billed as used with no unit yet; preview refuses while any"
}
},
"required": [
"mode",
"period",
"expiry_days",
"note",
"currency",
"packages",
"addons",
"unpriced",
"no_unit"
],
"additionalProperties": false
}ProposalDetail
{
"type": "object",
"properties": {
"proposal": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"version": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"status": {
"type": "string",
"enum": [
"draft",
"sent",
"viewed",
"signed",
"declined",
"expired",
"revoked",
"superseded"
]
},
"client_id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"template_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"campaign_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"offer_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"packet_id": {
"description": "The walkthrough it was sent in; present only when it's part of a walkthrough",
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"build": {
"description": "Drafts only",
"anyOf": [
{
"$ref": "#/components/schemas/PricedBuild"
},
{
"type": "null"
}
]
},
"preview": {
"description": "Drafts only",
"anyOf": [
{
"type": "object",
"properties": {
"preview_sha256": {
"type": "string"
},
"previewed_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"fresh_until": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"fresh": {
"type": "boolean"
},
"expires_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
}
},
"required": [
"preview_sha256",
"previewed_at",
"fresh_until",
"fresh",
"expires_at"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"updated_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
}
},
"required": [
"id",
"version",
"status",
"client_id",
"template_id",
"campaign_id",
"offer_id",
"created_at",
"updated_at"
],
"additionalProperties": {}
},
"signature": {
"anyOf": [
{
"type": "object",
"properties": {
"signed_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"typed_name": {
"type": "string"
},
"signer_title": {
"description": "Signed for a business client: the signer's title; absent otherwise",
"type": "string"
},
"signer_capacity": {
"description": "Signed by a represented client's representative: how they signed for the client; absent otherwise",
"type": "string",
"enum": [
"power_of_attorney",
"guardian",
"executor",
"personal_representative"
]
},
"on_behalf_of": {
"description": "Signed for a business client, or by a represented client's representative: who for; absent otherwise",
"type": "string"
},
"total_cents": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991,
"description": "Kept for compatibility: one-time plus yearly. Use totals, which also carries amounts billed every six months, quarterly, or weekly."
},
"monthly_cents": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991,
"description": "Kept for compatibility: the monthly amount. Use totals."
},
"totals": {
"description": "What the client agreed to pay: net of any discounts",
"$ref": "#/components/schemas/BillingTotals"
},
"currency": {
"type": "string"
},
"discounts": {
"description": "Discount lines that came off, each with its kind; present only when one did (as in the webhook events, /api/docs/webhooks)",
"type": "array",
"items": {
"type": "object",
"properties": {
"kind": {
"type": "string"
},
"label": {
"type": "string"
},
"amount_cents": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"kind",
"label",
"amount_cents"
],
"additionalProperties": {}
}
},
"listed_totals": {
"description": "The totals before discounts; present only with discounts",
"$ref": "#/components/schemas/BillingTotals"
},
"pdf": {
"type": "object",
"properties": {
"url": {
"type": [
"string",
"null"
]
},
"sha256": {
"type": [
"string",
"null"
]
},
"ready": {
"type": "boolean"
}
},
"required": [
"url",
"sha256",
"ready"
],
"additionalProperties": false
}
},
"required": [
"signed_at",
"typed_name",
"total_cents",
"monthly_cents",
"totals",
"currency",
"pdf"
],
"additionalProperties": {}
},
{
"type": "null"
}
]
},
"copied_people": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CopiedPerson"
}
},
"signing": {
"anyOf": [
{
"$ref": "#/components/schemas/Signing"
},
{
"type": "null"
}
],
"description": "Null with one signer, the client (people with role signer make more)"
},
"signers": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Signer"
},
"description": "Every signer, the client included; empty with one"
}
},
"required": [
"proposal",
"signature",
"copied_people",
"signing",
"signers"
],
"additionalProperties": false
}CopiedPerson
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"name": {
"type": "string"
},
"email": {
"type": "string"
},
"relationship": {
"type": "string",
"enum": [
"spouse",
"family",
"assistant",
"business_partner",
"other"
]
},
"role": {
"type": "string",
"enum": [
"copied",
"signer"
]
},
"signed_copy": {
"type": "boolean",
"description": "They get the signed copy"
},
"link_sent_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
],
"description": "When their view-only link was emailed; null if it wasn't"
},
"first_viewed_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"last_viewed_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"view_count": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"access_removed_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
],
"description": "Staff removed their access; their link no longer works"
}
},
"required": [
"id",
"name",
"email",
"relationship",
"role",
"signed_copy",
"link_sent_at",
"first_viewed_at",
"last_viewed_at",
"view_count",
"access_removed_at"
],
"additionalProperties": false
}Signing
{
"type": "object",
"properties": {
"rule": {
"type": "string",
"enum": [
"all",
"any"
],
"description": "all: every signer signs; any: any one of them"
},
"order": {
"anyOf": [
{
"type": "string",
"enum": [
"any",
"in_order"
]
},
{
"type": "null"
}
],
"description": "With all: any order, or one after another by position"
}
},
"required": [
"rule",
"order"
],
"additionalProperties": false
}Signer
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"email": {
"type": "string"
},
"position": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"client": {
"type": "boolean",
"description": "The client themselves"
},
"state": {
"anyOf": [
{
"type": "string",
"enum": [
"waiting",
"open",
"signed",
"declined",
"voided"
]
},
{
"type": "null"
}
],
"description": "Null on a draft"
},
"signed_at": {
"type": [
"string",
"null"
]
},
"declined_at": {
"type": [
"string",
"null"
]
},
"title": {
"description": "A business client's signer: their title, as staff entered it; absent otherwise",
"type": "string"
},
"signer_title": {
"description": "Signed for a business client: the title they confirmed; absent otherwise",
"type": "string"
},
"signer_capacity": {
"description": "Signed by a represented client's representative: how they signed for the client; absent otherwise",
"type": "string",
"enum": [
"power_of_attorney",
"guardian",
"executor",
"personal_representative"
]
},
"on_behalf_of": {
"description": "Signed for a business client, or by a represented client's representative: who for; absent otherwise",
"type": "string"
}
},
"required": [
"name",
"email",
"position",
"client",
"state",
"signed_at",
"declined_at"
],
"additionalProperties": false
}CopyResent
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"name": {
"type": "string"
},
"email": {
"type": "string"
},
"relationship": {
"type": "string",
"enum": [
"spouse",
"family",
"assistant",
"business_partner",
"other"
]
},
"role": {
"type": "string",
"enum": [
"copied",
"signer"
]
},
"signed_copy": {
"type": "boolean",
"description": "They get the signed copy"
},
"link_sent_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
],
"description": "When their view-only link was emailed; null if it wasn't"
},
"first_viewed_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"last_viewed_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"view_count": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"access_removed_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
],
"description": "Staff removed their access; their link no longer works"
},
"new_link": {
"type": "boolean",
"description": "A new link was made (the earlier one stopped); false when their link was reused"
}
},
"required": [
"id",
"name",
"email",
"relationship",
"role",
"signed_copy",
"link_sent_at",
"first_viewed_at",
"last_viewed_at",
"view_count",
"access_removed_at",
"new_link"
],
"additionalProperties": false
}Preview
{
"type": "object",
"properties": {
"preview_sha256": {
"type": "string"
},
"previewed_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"fresh_until": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"fresh": {
"type": "boolean"
},
"expires_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"totals": {
"$ref": "#/components/schemas/PricedBuild"
},
"document_url": {
"type": "string",
"description": "The rendered document; needs your API key, like the PDF"
}
},
"required": [
"preview_sha256",
"previewed_at",
"fresh_until",
"fresh",
"expires_at",
"totals",
"document_url"
],
"additionalProperties": false
}Sent
{
"type": "object",
"properties": {
"proposal": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"version": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"status": {
"type": "string",
"enum": [
"draft",
"sent",
"viewed",
"signed",
"declined",
"expired",
"revoked",
"superseded"
]
},
"client_id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"template_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"campaign_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"offer_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"packet_id": {
"description": "The walkthrough it was sent in; present only when it's part of a walkthrough",
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"build": {
"description": "Drafts only",
"anyOf": [
{
"$ref": "#/components/schemas/PricedBuild"
},
{
"type": "null"
}
]
},
"preview": {
"description": "Drafts only",
"anyOf": [
{
"type": "object",
"properties": {
"preview_sha256": {
"type": "string"
},
"previewed_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"fresh_until": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"fresh": {
"type": "boolean"
},
"expires_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
}
},
"required": [
"preview_sha256",
"previewed_at",
"fresh_until",
"fresh",
"expires_at"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"updated_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
}
},
"required": [
"id",
"version",
"status",
"client_id",
"template_id",
"campaign_id",
"offer_id",
"created_at",
"updated_at"
],
"additionalProperties": {}
},
"signature": {
"anyOf": [
{
"type": "object",
"properties": {
"signed_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"typed_name": {
"type": "string"
},
"signer_title": {
"description": "Signed for a business client: the signer's title; absent otherwise",
"type": "string"
},
"signer_capacity": {
"description": "Signed by a represented client's representative: how they signed for the client; absent otherwise",
"type": "string",
"enum": [
"power_of_attorney",
"guardian",
"executor",
"personal_representative"
]
},
"on_behalf_of": {
"description": "Signed for a business client, or by a represented client's representative: who for; absent otherwise",
"type": "string"
},
"total_cents": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991,
"description": "Kept for compatibility: one-time plus yearly. Use totals, which also carries amounts billed every six months, quarterly, or weekly."
},
"monthly_cents": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991,
"description": "Kept for compatibility: the monthly amount. Use totals."
},
"totals": {
"description": "What the client agreed to pay: net of any discounts",
"$ref": "#/components/schemas/BillingTotals"
},
"currency": {
"type": "string"
},
"discounts": {
"description": "Discount lines that came off, each with its kind; present only when one did (as in the webhook events, /api/docs/webhooks)",
"type": "array",
"items": {
"type": "object",
"properties": {
"kind": {
"type": "string"
},
"label": {
"type": "string"
},
"amount_cents": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"kind",
"label",
"amount_cents"
],
"additionalProperties": {}
}
},
"listed_totals": {
"description": "The totals before discounts; present only with discounts",
"$ref": "#/components/schemas/BillingTotals"
},
"pdf": {
"type": "object",
"properties": {
"url": {
"type": [
"string",
"null"
]
},
"sha256": {
"type": [
"string",
"null"
]
},
"ready": {
"type": "boolean"
}
},
"required": [
"url",
"sha256",
"ready"
],
"additionalProperties": false
}
},
"required": [
"signed_at",
"typed_name",
"total_cents",
"monthly_cents",
"totals",
"currency",
"pdf"
],
"additionalProperties": {}
},
{
"type": "null"
}
]
},
"emailed": {
"type": "boolean"
},
"credits": {
"anyOf": [
{
"type": "object",
"properties": {
"left": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"overage_used": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"overage_room": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"left",
"overage_used",
"overage_room"
],
"additionalProperties": false
},
{
"type": "null"
}
],
"description": "null before credits start for the business"
}
},
"required": [
"proposal",
"signature",
"emailed",
"credits"
],
"additionalProperties": false
}Withdrawn
{
"type": "object",
"properties": {
"proposal": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"version": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"status": {
"type": "string",
"enum": [
"draft",
"sent",
"viewed",
"signed",
"declined",
"expired",
"revoked",
"superseded"
]
},
"client_id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"template_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"campaign_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"offer_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"packet_id": {
"description": "The walkthrough it was sent in; present only when it's part of a walkthrough",
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"build": {
"description": "Drafts only",
"anyOf": [
{
"$ref": "#/components/schemas/PricedBuild"
},
{
"type": "null"
}
]
},
"preview": {
"description": "Drafts only",
"anyOf": [
{
"type": "object",
"properties": {
"preview_sha256": {
"type": "string"
},
"previewed_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"fresh_until": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"fresh": {
"type": "boolean"
},
"expires_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
}
},
"required": [
"preview_sha256",
"previewed_at",
"fresh_until",
"fresh",
"expires_at"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"updated_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
}
},
"required": [
"id",
"version",
"status",
"client_id",
"template_id",
"campaign_id",
"offer_id",
"created_at",
"updated_at"
],
"additionalProperties": {}
},
"signature": {
"anyOf": [
{
"type": "object",
"properties": {
"signed_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"typed_name": {
"type": "string"
},
"signer_title": {
"description": "Signed for a business client: the signer's title; absent otherwise",
"type": "string"
},
"signer_capacity": {
"description": "Signed by a represented client's representative: how they signed for the client; absent otherwise",
"type": "string",
"enum": [
"power_of_attorney",
"guardian",
"executor",
"personal_representative"
]
},
"on_behalf_of": {
"description": "Signed for a business client, or by a represented client's representative: who for; absent otherwise",
"type": "string"
},
"total_cents": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991,
"description": "Kept for compatibility: one-time plus yearly. Use totals, which also carries amounts billed every six months, quarterly, or weekly."
},
"monthly_cents": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991,
"description": "Kept for compatibility: the monthly amount. Use totals."
},
"totals": {
"description": "What the client agreed to pay: net of any discounts",
"$ref": "#/components/schemas/BillingTotals"
},
"currency": {
"type": "string"
},
"discounts": {
"description": "Discount lines that came off, each with its kind; present only when one did (as in the webhook events, /api/docs/webhooks)",
"type": "array",
"items": {
"type": "object",
"properties": {
"kind": {
"type": "string"
},
"label": {
"type": "string"
},
"amount_cents": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"kind",
"label",
"amount_cents"
],
"additionalProperties": {}
}
},
"listed_totals": {
"description": "The totals before discounts; present only with discounts",
"$ref": "#/components/schemas/BillingTotals"
},
"pdf": {
"type": "object",
"properties": {
"url": {
"type": [
"string",
"null"
]
},
"sha256": {
"type": [
"string",
"null"
]
},
"ready": {
"type": "boolean"
}
},
"required": [
"url",
"sha256",
"ready"
],
"additionalProperties": false
}
},
"required": [
"signed_at",
"typed_name",
"total_cents",
"monthly_cents",
"totals",
"currency",
"pdf"
],
"additionalProperties": {}
},
{
"type": "null"
}
]
},
"client_emailed": {
"type": "boolean"
},
"credits": {
"anyOf": [
{
"type": "object",
"properties": {
"left": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"overage_used": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"overage_room": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"left",
"overage_used",
"overage_room"
],
"additionalProperties": false
},
{
"type": "null"
}
],
"description": "null before credits start for the business"
}
},
"required": [
"proposal",
"signature",
"client_emailed",
"credits"
],
"additionalProperties": false
}Resent
{
"type": "object",
"properties": {
"proposal": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"version": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"status": {
"type": "string",
"enum": [
"draft",
"sent",
"viewed",
"signed",
"declined",
"expired",
"revoked",
"superseded"
]
},
"client_id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"template_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"campaign_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"offer_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"packet_id": {
"description": "The walkthrough it was sent in; present only when it's part of a walkthrough",
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"build": {
"description": "Drafts only",
"anyOf": [
{
"$ref": "#/components/schemas/PricedBuild"
},
{
"type": "null"
}
]
},
"preview": {
"description": "Drafts only",
"anyOf": [
{
"type": "object",
"properties": {
"preview_sha256": {
"type": "string"
},
"previewed_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"fresh_until": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"fresh": {
"type": "boolean"
},
"expires_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
}
},
"required": [
"preview_sha256",
"previewed_at",
"fresh_until",
"fresh",
"expires_at"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"updated_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
}
},
"required": [
"id",
"version",
"status",
"client_id",
"template_id",
"campaign_id",
"offer_id",
"created_at",
"updated_at"
],
"additionalProperties": {}
},
"signature": {
"anyOf": [
{
"type": "object",
"properties": {
"signed_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"typed_name": {
"type": "string"
},
"signer_title": {
"description": "Signed for a business client: the signer's title; absent otherwise",
"type": "string"
},
"signer_capacity": {
"description": "Signed by a represented client's representative: how they signed for the client; absent otherwise",
"type": "string",
"enum": [
"power_of_attorney",
"guardian",
"executor",
"personal_representative"
]
},
"on_behalf_of": {
"description": "Signed for a business client, or by a represented client's representative: who for; absent otherwise",
"type": "string"
},
"total_cents": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991,
"description": "Kept for compatibility: one-time plus yearly. Use totals, which also carries amounts billed every six months, quarterly, or weekly."
},
"monthly_cents": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991,
"description": "Kept for compatibility: the monthly amount. Use totals."
},
"totals": {
"description": "What the client agreed to pay: net of any discounts",
"$ref": "#/components/schemas/BillingTotals"
},
"currency": {
"type": "string"
},
"discounts": {
"description": "Discount lines that came off, each with its kind; present only when one did (as in the webhook events, /api/docs/webhooks)",
"type": "array",
"items": {
"type": "object",
"properties": {
"kind": {
"type": "string"
},
"label": {
"type": "string"
},
"amount_cents": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"kind",
"label",
"amount_cents"
],
"additionalProperties": {}
}
},
"listed_totals": {
"description": "The totals before discounts; present only with discounts",
"$ref": "#/components/schemas/BillingTotals"
},
"pdf": {
"type": "object",
"properties": {
"url": {
"type": [
"string",
"null"
]
},
"sha256": {
"type": [
"string",
"null"
]
},
"ready": {
"type": "boolean"
}
},
"required": [
"url",
"sha256",
"ready"
],
"additionalProperties": false
}
},
"required": [
"signed_at",
"typed_name",
"total_cents",
"monthly_cents",
"totals",
"currency",
"pdf"
],
"additionalProperties": {}
},
{
"type": "null"
}
]
},
"emailed": {
"type": "boolean",
"description": "false when the business has no email sender: proposal.sent tells its automation"
},
"expires_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
}
},
"required": [
"proposal",
"signature",
"emailed",
"expires_at"
],
"additionalProperties": false
}Extended
{
"type": "object",
"properties": {
"proposal": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"version": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"status": {
"type": "string",
"enum": [
"draft",
"sent",
"viewed",
"signed",
"declined",
"expired",
"revoked",
"superseded"
]
},
"client_id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"template_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"campaign_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"offer_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"packet_id": {
"description": "The walkthrough it was sent in; present only when it's part of a walkthrough",
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"build": {
"description": "Drafts only",
"anyOf": [
{
"$ref": "#/components/schemas/PricedBuild"
},
{
"type": "null"
}
]
},
"preview": {
"description": "Drafts only",
"anyOf": [
{
"type": "object",
"properties": {
"preview_sha256": {
"type": "string"
},
"previewed_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"fresh_until": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"fresh": {
"type": "boolean"
},
"expires_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
}
},
"required": [
"preview_sha256",
"previewed_at",
"fresh_until",
"fresh",
"expires_at"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"updated_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
}
},
"required": [
"id",
"version",
"status",
"client_id",
"template_id",
"campaign_id",
"offer_id",
"created_at",
"updated_at"
],
"additionalProperties": {}
},
"signature": {
"anyOf": [
{
"type": "object",
"properties": {
"signed_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"typed_name": {
"type": "string"
},
"signer_title": {
"description": "Signed for a business client: the signer's title; absent otherwise",
"type": "string"
},
"signer_capacity": {
"description": "Signed by a represented client's representative: how they signed for the client; absent otherwise",
"type": "string",
"enum": [
"power_of_attorney",
"guardian",
"executor",
"personal_representative"
]
},
"on_behalf_of": {
"description": "Signed for a business client, or by a represented client's representative: who for; absent otherwise",
"type": "string"
},
"total_cents": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991,
"description": "Kept for compatibility: one-time plus yearly. Use totals, which also carries amounts billed every six months, quarterly, or weekly."
},
"monthly_cents": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991,
"description": "Kept for compatibility: the monthly amount. Use totals."
},
"totals": {
"description": "What the client agreed to pay: net of any discounts",
"$ref": "#/components/schemas/BillingTotals"
},
"currency": {
"type": "string"
},
"discounts": {
"description": "Discount lines that came off, each with its kind; present only when one did (as in the webhook events, /api/docs/webhooks)",
"type": "array",
"items": {
"type": "object",
"properties": {
"kind": {
"type": "string"
},
"label": {
"type": "string"
},
"amount_cents": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"kind",
"label",
"amount_cents"
],
"additionalProperties": {}
}
},
"listed_totals": {
"description": "The totals before discounts; present only with discounts",
"$ref": "#/components/schemas/BillingTotals"
},
"pdf": {
"type": "object",
"properties": {
"url": {
"type": [
"string",
"null"
]
},
"sha256": {
"type": [
"string",
"null"
]
},
"ready": {
"type": "boolean"
}
},
"required": [
"url",
"sha256",
"ready"
],
"additionalProperties": false
}
},
"required": [
"signed_at",
"typed_name",
"total_cents",
"monthly_cents",
"totals",
"currency",
"pdf"
],
"additionalProperties": {}
},
{
"type": "null"
}
]
},
"reopened": {
"type": "boolean",
"description": "true when it had expired and extending it reopened it"
},
"emailed": {
"type": "boolean",
"description": "true when an email with the new date was queued (or held while email is paused); false when notify_client was false or there's no email sender"
}
},
"required": [
"proposal",
"signature",
"reopened",
"emailed"
],
"additionalProperties": false,
"description": "The proposal as it is now: its proposal block's expires_at is the new deadline and original_expires_at the respond-by date the document printed."
}Revision
{
"type": "object",
"properties": {
"proposal": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"version": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"status": {
"type": "string",
"enum": [
"draft",
"sent",
"viewed",
"signed",
"declined",
"expired",
"revoked",
"superseded"
]
},
"client_id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"template_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"campaign_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"offer_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"packet_id": {
"description": "The walkthrough it was sent in; present only when it's part of a walkthrough",
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"build": {
"description": "Drafts only",
"anyOf": [
{
"$ref": "#/components/schemas/PricedBuild"
},
{
"type": "null"
}
]
},
"preview": {
"description": "Drafts only",
"anyOf": [
{
"type": "object",
"properties": {
"preview_sha256": {
"type": "string"
},
"previewed_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"fresh_until": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"fresh": {
"type": "boolean"
},
"expires_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
}
},
"required": [
"preview_sha256",
"previewed_at",
"fresh_until",
"fresh",
"expires_at"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"updated_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
}
},
"required": [
"id",
"version",
"status",
"client_id",
"template_id",
"campaign_id",
"offer_id",
"created_at",
"updated_at"
],
"additionalProperties": {}
},
"signature": {
"anyOf": [
{
"type": "object",
"properties": {
"signed_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"typed_name": {
"type": "string"
},
"signer_title": {
"description": "Signed for a business client: the signer's title; absent otherwise",
"type": "string"
},
"signer_capacity": {
"description": "Signed by a represented client's representative: how they signed for the client; absent otherwise",
"type": "string",
"enum": [
"power_of_attorney",
"guardian",
"executor",
"personal_representative"
]
},
"on_behalf_of": {
"description": "Signed for a business client, or by a represented client's representative: who for; absent otherwise",
"type": "string"
},
"total_cents": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991,
"description": "Kept for compatibility: one-time plus yearly. Use totals, which also carries amounts billed every six months, quarterly, or weekly."
},
"monthly_cents": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991,
"description": "Kept for compatibility: the monthly amount. Use totals."
},
"totals": {
"description": "What the client agreed to pay: net of any discounts",
"$ref": "#/components/schemas/BillingTotals"
},
"currency": {
"type": "string"
},
"discounts": {
"description": "Discount lines that came off, each with its kind; present only when one did (as in the webhook events, /api/docs/webhooks)",
"type": "array",
"items": {
"type": "object",
"properties": {
"kind": {
"type": "string"
},
"label": {
"type": "string"
},
"amount_cents": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"kind",
"label",
"amount_cents"
],
"additionalProperties": {}
}
},
"listed_totals": {
"description": "The totals before discounts; present only with discounts",
"$ref": "#/components/schemas/BillingTotals"
},
"pdf": {
"type": "object",
"properties": {
"url": {
"type": [
"string",
"null"
]
},
"sha256": {
"type": [
"string",
"null"
]
},
"ready": {
"type": "boolean"
}
},
"required": [
"url",
"sha256",
"ready"
],
"additionalProperties": false
}
},
"required": [
"signed_at",
"typed_name",
"total_cents",
"monthly_cents",
"totals",
"currency",
"pdf"
],
"additionalProperties": {}
},
{
"type": "null"
}
]
},
"template_changed": {
"type": "boolean"
}
},
"required": [
"proposal",
"signature",
"template_changed"
],
"additionalProperties": false
}SigningLink
{
"type": "object",
"properties": {
"url": {
"type": "string"
},
"expires_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
}
},
"required": [
"url",
"expires_at"
],
"additionalProperties": false
}Document
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"kind": {
"type": "string",
"enum": [
"agreement",
"consent"
]
},
"version": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"status": {
"type": "string",
"enum": [
"draft",
"sent",
"viewed",
"signed",
"declined",
"expired",
"revoked",
"superseded"
]
},
"template": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"name": {
"type": "string"
}
},
"required": [
"id",
"name"
],
"additionalProperties": false
},
"client": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"external_id": {
"type": [
"string",
"null"
]
},
"display_name": {
"type": "string"
}
},
"required": [
"id",
"external_id",
"display_name"
],
"additionalProperties": false
},
"campaign_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"packet_id": {
"description": "The walkthrough it was sent in; present only when it's part of a walkthrough",
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"supersedes_id": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"sent_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"expires_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
],
"description": "When it ends: the deadline after any extension"
},
"original_expires_at": {
"description": "The respond-by date the document shows; present only once the deadline was extended",
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"resolved_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"updated_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"signers": {
"type": "array",
"items": {
"type": "object",
"properties": {
"position": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"client": {
"type": "boolean",
"description": "The client themselves"
},
"name": {
"type": "string"
},
"state": {
"type": "string",
"enum": [
"waiting",
"open",
"signed",
"declined",
"voided"
]
},
"signed_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"declined_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"signer_title": {
"description": "Signed for a business client: the title they confirmed; absent otherwise",
"type": "string"
},
"signer_capacity": {
"description": "Signed by a represented client's representative: how they signed for the client; absent otherwise",
"type": "string",
"enum": [
"power_of_attorney",
"guardian",
"executor",
"personal_representative"
]
},
"on_behalf_of": {
"description": "Signed for a business client, or by a represented client's representative: who for; absent otherwise",
"type": "string"
}
},
"required": [
"position",
"client",
"name",
"state",
"signed_at",
"declined_at"
],
"additionalProperties": false
},
"description": "Every signer, the client included; empty with one. Never an email or a link."
},
"signature": {
"anyOf": [
{
"type": "object",
"properties": {
"signed_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"typed_name": {
"type": "string"
},
"signer_title": {
"description": "Signed for a business client: the signer's title; absent otherwise",
"type": "string"
},
"signer_capacity": {
"description": "Signed by a represented client's representative: how they signed for the client; absent otherwise",
"type": "string",
"enum": [
"power_of_attorney",
"guardian",
"executor",
"personal_representative"
]
},
"on_behalf_of": {
"description": "Signed for a business client, or by a represented client's representative: who for; absent otherwise",
"type": "string"
},
"signing_method": {
"type": "string"
},
"consents": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"title": {
"type": "string"
},
"version": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"id",
"title",
"version"
],
"additionalProperties": false
},
"description": "The business's consent documents agreed to on it"
}
},
"required": [
"signed_at",
"typed_name",
"signing_method",
"consents"
],
"additionalProperties": false
},
{
"type": "null"
}
],
"description": "When it's signed"
},
"pdf_ready": {
"type": "boolean"
}
},
"required": [
"id",
"kind",
"version",
"status",
"template",
"client",
"campaign_id",
"supersedes_id",
"sent_at",
"expires_at",
"resolved_at",
"created_at",
"updated_at",
"signers",
"signature",
"pdf_ready"
],
"additionalProperties": false,
"description": "An agreement or a consent sent on its own. It has no price."
}Event
{
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "evt_ followed by 32 hex characters, as in the webhook"
},
"type": {
"type": "string"
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"tenant": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"slug": {
"type": "string"
}
},
"required": [
"id",
"slug"
],
"additionalProperties": false
},
"data": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {},
"description": "The webhook payload. signing_url and resume_url are null (with redacted: true) unless the key has proposals:links."
},
"delivery": {
"type": "string",
"enum": [
"delivered",
"due",
"failed",
"off"
]
}
},
"required": [
"id",
"type",
"created_at",
"tenant",
"data",
"delivery"
],
"additionalProperties": false
}