Sending invoices and quotes
Sending is asynchronous: the send routes answer 202, a send moves from queued to sent or failed, and a failed send tells you why.
Sending an invoice or a quote is asynchronous. POST …/invoices/{id}/send and POST …/quotes/{id}/send queue the document and answer 202 Accepted at once with the send; they no longer answer 200 once the document has been sent. Read the outcome with the send, or with the document's sendState. Every path below is under /api/v1/workspaces/{slug}.
The flow
POST …/invoices/{id}/send(invoices:write, toolsend_invoice) andPOST …/quotes/{id}/send(quotes:write, toolsend_quote) answer202with the send:id,documentId,documentType,state,failureReason,emailOutcome,attempts,createdAtandfinishedAt.GET …/invoices/{id}/sends/{sendId}(invoices:read, toolget_invoice_send) andGET …/quotes/{id}/sends/{sendId}(quotes:read, toolget_quote_send) return that send as it stands now. A send id that belongs to another document is404.stateisqueuedorworkingwhile the worker runs, thensentorfailed. While a send is open, the invoice or quote carriessendStateofqueuedorworking; otherwise it isnull.- The document stays a draft until the send commits. Then it is
sentand locked, an invoice with its pay link and a quote with the client's approval link, and the client is emailed the PDF.
The outcome
- A
sentsend has anemailOutcome:sent,skipped(the client has no email address) orfailed(the document is sent but the email could not be delivered). - A
failedsend has afailureReason:gateway_unavailable,pdf_unavailableorconflict(a transient failure, retried three times, no sooner than 15 seconds, 1 minute and 5 minutes after each failure, before the send fails);gateway_rejected(the payment gateway refused its credentials) orgateway_test_mode(a test-mode key in production), which fail it at once; andquote_expired,not_sendable,feature_locked,billing_read_only,interrupted,requester_not_allowedandunexpected. - Nothing is sent when a send fails, and the document stays a draft. Fix the cause and POST again.
Refusals and retries
- A second POST while a send is open is
409 send_in_progress. A document that is no longer a draft is409 invalid_status_transition. A quote whose validity has passed is409 quote_expired. - Both routes honour
Idempotency-Key: a replay returns the same send. - The worker picks up queued sends every minute.
Finding out that a send failed
When a person asked for a send and it fails for good, Rokn publishes invoice.send_failed or quote.send_failed to that person and they are notified. A send queued by an API key or by automation has no requester and publishes nothing: poll the send, or the document's sendState, instead.
POST /api/v1/workspaces/acme/invoices/inv_123/send
Authorization: Bearer <token>
Idempotency-Key: 6f1c2e0a-…
# 202 → { "id": "snd_1", "documentType": "invoice", "state": "queued", … }
GET /api/v1/workspaces/acme/invoices/inv_123/sends/snd_1
Authorization: Bearer <token>
# 200 → { "state": "sent", "emailOutcome": "sent", "failureReason": null, … }