REST API
Retries and idempotency
A network can drop an answer after the service did the work. These rules make a retry safe.
Create
Send an Idempotency-Key header with a create:
Idempotency-Key: crm-contract-1042
- The first call creates the request and answers 201.
- A retry with the same key answers 200 with the same request. Nothing new is created.
- Keys are unique per organisation, not per API key. A retry after a key rotation still finds the first request. Two systems of one organisation that use the same key value get one request, so prefix the value with the name of your system.
- The service does not compare the bodies. A retry with the same key and a different body gets the first request back, not an error.
- After you delete a draft, the same key creates a new request.
- An empty key, or one over 255 characters, is a 400
idempotency_key_invalid.
Send and cancel
Both are idempotent by state. A second send of a request that waits for
signatures or is completed answers 200 with its current state; a send of a
declined or expired request is 409 request_not_draft. A second cancel of a
request that is cancelled already answers 200.
Replace a draft
PUT needs an If-Match header with the ETag of your last read. If the draft
changed since then, the answer is 412 precondition_failed: read it again, then
apply your change to the new version. A PUT without If-Match gets 428
precondition_required. If-Match: * replaces the draft whatever its version
is.
Resend an invitation
A resend schedules an email, which goes out within seconds; the
invitation_resent event of the request shows when it went out. Two calls
while the first waits send one email. After the email, the signer gets no
other invitation email for 3 minutes: a resend in that time gives
429 resend_too_soon, with the seconds to wait in Retry-After. The send
is still at least once: if the worker fails after the email, its retry sends
a second one.
If you retry a resend after a timeout and get resend_too_soon, the signer
got an invitation email in the last 3 minutes: from your earlier call, or
from the first invitation. Do not resend again. The events of the request
show which: an invitation_resent or a signer_invited event of the signer.