Send for signature

Send the contract PDF to the dealer signer and the Spyne signers through DocuSign. The contract moves to Contract-Pending-User-Signature.

POSThttps://api.spyne.ai/credit/v6/contracting/send-for-signature
AuthBearer token (console user)Rate limitNot documentedProcessingSynchronous; waits for DocuSign to create the envelope and for the stage update.

The call first checks that the contract belongs to the dealer group, is in Contract-Initiated, has a PDF location and has a signer email. It then fetches the PDF and creates a DocuSign envelope with two signing steps: the dealer signer first, then Spyne signers. Copies go to the console user who sent it and to any valid signatoryDetails.clientPOCs. The contract ID and dealer group ID are stored on the envelope so the webhook can find the contract later.

After the envelope is created, the call:

  • sets the contract stage to Contract-Pending-User-Signature,
  • records the envelope ID, sender and send date in the contract history,
  • writes a stage log entry,
  • moves the dealer group stage to Contract-Pending-User-Signature.

For test accounts, the Spyne signer and copy recipients are replaced with test lists.

Send the bearer token of a signed-in Spyne Console user in Authorization: Bearer YOUR_TOKEN. The token is checked against the user validation endpoint on every call.

Before you call it

  • The contract must be in Contract-Initiated, so submit it first with Save or submit a contract.
  • The contract PDF must already be uploaded to the contract's file location. If the file is missing, the call returns 400.
  • The stored contract must have signatoryDetails.email.
  • The call is synchronous. It waits for DocuSign to create the envelope and for the stage update. DocuSign sends the emails itself. The rate limit is not documented.

Request

Requiredalways send
Request checklist
  1. Authenticate: send the Authorization: Bearer YOUR_TOKEN and Content-Type: application/json headers.
  2. Name the contract: send enterpriseId and contractId.
  3. Keep the envelope ID: keep data.docusignEnvelopeId for support and tracing.

Headers

ParameterTypeRequiredDescription
AuthorizationstringRequiredBearer YOUR_TOKEN
Content-TypestringRequiredapplication/json

Body

ParameterTypeRequiredDescription
enterpriseIdstringRequiredDealer group ID. It must match the contract.
contractIdstringRequiredContract ID from Save or submit a contract.

Sample request

curl -X POST "https://api.spyne.ai/credit/v6/contracting/send-for-signature" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "enterpriseId": "ENTERPRISE_ID", "contractId": "CONTRACT_ID" }'
import requests

res = requests.post(
    "https://api.spyne.ai/credit/v6/contracting/send-for-signature",
    json={"enterpriseId": "ENTERPRISE_ID", "contractId": "CONTRACT_ID"},
    headers={"Authorization": "Bearer YOUR_TOKEN"},
)
print(res.status_code, res.json())
const res = await fetch("https://api.spyne.ai/credit/v6/contracting/send-for-signature", {
  method: "POST",
  headers: { Authorization: "Bearer YOUR_TOKEN", "Content-Type": "application/json" },
  body: JSON.stringify({ enterpriseId: "ENTERPRISE_ID", contractId: "CONTRACT_ID" }),
});
console.log(res.status, await res.json());

Sample response

{
  "message": "Contract sent for signature successfully. Customer will receive DocuSign email.",
  "error": false,
  "code": "SUCCESS",
  "details": null,
  "data": {
    "success": true,
    "contractId": "CONTRACT_ID",
    "enterpriseId": "ENTERPRISE_ID",
    "docusignEnvelopeId": "ENVELOPE_ID",
    "status": "sent",
    "stage": "Contract-Pending-User-Signature",
    "sentTo": "[email protected]",
    "sentBy": "USER_ID",
    "sentDate": "2026-01-01T00:00:00.000Z"
  }
}
{
  "message": "Contract must be in 'Contract-Initiated' stage. Current stage: Draft",
  "error": true,
  "code": "INVALID_STAGE",
  "details": null,
  "data": null
}
{ "message": "Invalid Token", "error": true, "code": "ERROR_AUTH_401", "details": null, "data": null }
{ "message": "Contract not found", "error": true, "code": "CONTRACT_NOT_FOUND", "details": null, "data": null }
{
  "message": "DocuSign send failed: <error message>",
  "error": true,
  "code": "SERVER_ERROR",
  "details": null,
  "data": null
}

Response parameters

ParameterTypeDescription
data.successbooleantrue when the envelope was created.
data.contractIdstringContract ID.
data.enterpriseIdstringDealer group ID.
data.docusignEnvelopeIdstringDocuSign envelope ID.
data.statusstringAlways sent.
data.stagestringNew contract stage, Contract-Pending-User-Signature.
data.sentTostringDealer signer email.
data.sentBystringUser ID of the console user who sent it.
data.sentDatestringSend time (ISO 8601).

Errors

StatusCodeWhen it happens
400(framework)enterpriseId or contractId is missing. The framework rejects the request before the handler runs. The body is not documented in code.
400ENTERPRISE_MISMATCHThe contract belongs to another dealer group.
400INVALID_STAGEThe contract is not in Contract-Initiated. A second send of the same contract returns this.
400PDF_NOT_GENERATEDThe contract has no PDF location.
400SIGNATORY_DETAILS_MISSINGThe stored payload has no signatoryDetails.
400SIGNATORY_EMAIL_MISSINGThe stored payload has no signer email.
400PDF_NOT_FOUND_IN_S3The PDF file was not uploaded.
401ERROR_AUTH_401No Bearer token, or the token failed validation.
404CONTRACT_NOT_FOUNDNo contract has this ID.
408ERROR_REQ_TIMEOUT_408The token validation call could not connect.
500SERVER_ERRORDocuSign rejected the envelope, or another error occurred.

What happens next

The dealer signer gets a DocuSign email. When they sign, and again when all parties have signed, DocuSign calls Receive DocuSign events. To remind the signer later, the console calls POST /credit/v6/contracting/resend-for-signature with the same body.

Called before: Save or submit a contract. Called after: Receive DocuSign events, called by DocuSign.


Did this page help you?