Appearance
Idempotency
A network can fail after JustDocs has done the work but before you hear back. Retrying could then create a second document or send a request twice. An idempotency key prevents that. Calls with the same key do the work once.
Which calls take one
| Operation | REST | MCP |
|---|---|---|
| Create a template | POST /templates | create_template |
| Start a document | POST /documents | start_document |
| Create a signing request | POST /signing-requests | create_signing_request |
| Send a signing request | POST /signing-requests/{id}/send | send_signing_request |
| Send an intake link | POST /intake-requests | create_intake_request |
In the REST API, send it as a header. In MCP, pass the idempotency_key argument.
http
Idempotency-Key: nda-acme-2026-11-03A key is 8 to 100 letters, digits, - or _. A UUID works, and so does your own record's id.
How it behaves
- The first call does the work and remembers what it made.
- A retry with the same key returns what the first call made, without doing it again. This includes a send that's waiting for approval.
- A retry while the first call is still running gets
409 A call with this Idempotency-Key is still in progress; retry shortly. Wait a moment and retry with the same key. - The same key on something different is refused with
409. Its message says the key "was already used for a different call" or "for a different request". Not every combination of operations is compared, so don't rely on this check. Give each action its own key. - If the first call fails, nothing is remembered, and you can retry with the same key after fixing the problem. A template whose text has a mistake is refused before the key is used at all.
- Creating and sending at once (
send: true) makes the request first. If the request was made but the send failed, a retry with the same key returns that request and tries the send again. It doesn't apply a changed body. To change the request, use a new key.
Keys belong to the API key that sent them, so two of your integrations can't collide.
Choosing keys
Use one key per action you mean to happen once, and reuse it only for retries of that action. A good key comes from your own data, such as deal-4821-nda-send. Then a retry after a crash finds the first result, even in a new process.
js
async function sendOnce(dealId, body) {
for (let attempt = 1; ; attempt++) {
const response = await fetch("https://tryjustdocs.com/api/v1/signing-requests", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.JUSTDOCS_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": `deal-${dealId}-nda`,
},
body: JSON.stringify(body),
}).catch(() => null);
if (response && response.status !== 409 && response.status < 500) return response;
if (attempt === 5) throw new Error("JustDocs didn't answer");
await new Promise((done) => setTimeout(done, 2 ** attempt * 500));
}
}The 409 this retries is the "still in progress" one. A 409 for a key used on something different won't change on retry, so stop after a few attempts.