Skip to content

Send a contract

POST/v1/organization/{orgId}/crm/contracts

US Region: https://public-api.sessionboard.com · EU Region: https://public-api-eu.sessionboard.com

Creates a contract for the contact from a published template and sends it for signature with Sessionboard e-sign: the signer is emailed a link to the signing page. This reaches someone outside the organization and cannot be taken back, only voided, so confirm the recipient with the person first. Sending makes the contact an active contact. Requires write:crm. Refused for a key restricted to particular events. Also at POST /v1/org/{orgId}/crm/contracts, and at POST /v1/crm/contracts with the organization taken from the token.

Request example

Terminal window
curl --request POST \
--url 'https://public-api.sessionboard.com/v1/organization/{orgId}/crm/contracts' \
--header 'x-access-token: <api-token>' \
--header 'Content-Type: application/json' \
--data '{
"contactId": "<string>",
"templateId": "<string>",
"title": "<string>",
"eventId": 123,
"emailSubject": "<string>",
"emailMessage": "<string>"
}'

Try it

Authorization

Your token stays in this page. It is sent only to the region above and is never saved; it is gone when you leave or reload the page.

Path parameters
Body application/json
POST

Authorizations

  • x-access-tokenstringheader

    Organization API token. Generate from Organization Settings → API Tokens.

  • AuthorizationBearer <token>headeror

    OAuth 2.1 access token. Obtained via the OAuth PKCE flow at /oauth/token.

Send one of these. See Authentication.

Path parameters

  • orgIdstringpathrequired

    Your organization ID. Any other organization returns 404.

Request body

application/jsonrequired

  • contactIdstringrequired

    Who signs.

  • templateIdstringrequired

    A published template, from GET …/crm/contract-templates.

  • titlestring
    Max length
    200
  • eventIdinteger

    The event the agreement is for: its branding and variables.

  • emailSubjectstring
    Max length
    200
  • emailMessagestring
    Max length
    5000
{
"contactId": "<string>",
"templateId": "<string>",
"title": "<string>",
"eventId": 123,
"emailSubject": "<string>",
"emailMessage": "<string>"
}

Responses

201application/json

Created

  • successboolean
  • payloadCrmContract
    Show child attributes
    • idstring
    • titlestring
    • statusstring

      delivered: the signer opened the signing page. completed: everyone signed.

      Allowed values
      "created", "sent", "delivered", "completed", "declined", "voided"
    • sourcestring

      How it was sent: native is Sessionboard e-sign.

    • contactobject | null
      Show child attributes
      • idstring
      • namestring
      • emailstring<email>
    • templateobject | null
      Show child attributes
      • idstring
      • namestring
    • signer_emailstring<email> | null
    • has_pdfboolean

      The signed PDF is ready.

    • sent_atstring<date-time> | null
    • signed_atstring<date-time> | null
    • voided_atstring<date-time> | null
    • updated_atstring<date-time>

400application/json

VALIDATION_ERROR: the body or a path id does not match the schema.

  • successboolean
  • errorstring
    Allowed values
    "VALIDATION_ERROR", "SCOPE_REQUIRED", "ORG_WIDE_TOKEN_REQUIRED", "FORBIDDEN", "NOT_FOUND", "CONFLICT", "QUOTA_EXCEEDED"
  • codestring

    A more specific reason: exists, read_only, platform_customer.

  • messagestringrequired
  • contactCrmContact

    With code: exists: the contact that has the email.

    Show child attributes
    • idstring
    • first_namestring
    • last_namestring | null
    • namestring
    • emailstring<email>
    • companystring | null
    • titlestring | null

      Job title.

    • avatar_urlstring | null
    • typesstring[]
      Allowed values
      "speaker", "sme", "influencer", "exhibitor", "sponsor"
    • tagsCrmTag[]
      Show child attributes
      • idstring
      • namestring
    • events_countinteger
    • sessions_countinteger
    • last_activity_atstring<date-time> | null
    • activeboolean

      An active contact in the last 365 days.

    • sourcestring | null

      Where the contact came from.

    • created_atstring<date-time>
    • hrefstring

      The contact in Sessionboard CRM.

    • stageobject | null

      The contact's pipeline stage; null when not in the pipeline.

      Show child attributes
      • idstring
      • labelstring

401

Missing, invalid or expired token.

403application/json

  • SCOPE_REQUIRED: the token lacks write:crm (or read:crm for the POSTs that only read).
  • ORG_WIDE_TOKEN_REQUIRED: the key is restricted to particular events.
  • code: plan_read_only (or read_only): the CRM trial or plan has ended; everything can still be read.
  • code: platform_customer: the organization works with Sessionboard on a platform contract, so its contacts are in the Sessionboard platform.
  • code: FEATURE_NOT_ENABLED: contracts are not turned on for the organization (contracts operations only).
  • FORBIDDEN with no code: the token's user lacks the Contacts permission the change needs (connecting and disconnecting apps need an organization admin).
  • successboolean
  • errorstring
    Allowed values
    "VALIDATION_ERROR", "SCOPE_REQUIRED", "ORG_WIDE_TOKEN_REQUIRED", "FORBIDDEN", "NOT_FOUND", "CONFLICT", "QUOTA_EXCEEDED"
  • codestring

    A more specific reason: exists, read_only, platform_customer.

  • messagestringrequired
  • contactCrmContact

    With code: exists: the contact that has the email.

    Show child attributes
    • idstring
    • first_namestring
    • last_namestring | null
    • namestring
    • emailstring<email>
    • companystring | null
    • titlestring | null

      Job title.

    • avatar_urlstring | null
    • typesstring[]
      Allowed values
      "speaker", "sme", "influencer", "exhibitor", "sponsor"
    • tagsCrmTag[]
      Show child attributes
      • idstring
      • namestring
    • events_countinteger
    • sessions_countinteger
    • last_activity_atstring<date-time> | null
    • activeboolean

      An active contact in the last 365 days.

    • sourcestring | null

      Where the contact came from.

    • created_atstring<date-time>
    • hrefstring

      The contact in Sessionboard CRM.

    • stageobject | null

      The contact's pipeline stage; null when not in the pipeline.

      Show child attributes
      • idstring
      • labelstring

404application/json

NOT_FOUND: orgId is not the token's organization, or the contact, tag or app is not in it.

  • successboolean
  • errorstring
    Allowed values
    "VALIDATION_ERROR", "SCOPE_REQUIRED", "ORG_WIDE_TOKEN_REQUIRED", "FORBIDDEN", "NOT_FOUND", "CONFLICT", "QUOTA_EXCEEDED"
  • codestring

    A more specific reason: exists, read_only, platform_customer.

  • messagestringrequired
  • contactCrmContact

    With code: exists: the contact that has the email.

    Show child attributes
    • idstring
    • first_namestring
    • last_namestring | null
    • namestring
    • emailstring<email>
    • companystring | null
    • titlestring | null

      Job title.

    • avatar_urlstring | null
    • typesstring[]
      Allowed values
      "speaker", "sme", "influencer", "exhibitor", "sponsor"
    • tagsCrmTag[]
      Show child attributes
      • idstring
      • namestring
    • events_countinteger
    • sessions_countinteger
    • last_activity_atstring<date-time> | null
    • activeboolean

      An active contact in the last 365 days.

    • sourcestring | null

      Where the contact came from.

    • created_atstring<date-time>
    • hrefstring

      The contact in Sessionboard CRM.

    • stageobject | null

      The contact's pipeline stage; null when not in the pipeline.

      Show child attributes
      • idstring
      • labelstring

409application/json

CONFLICT: the contract is not in a state that allows this (already completed, declined or voided), or the contact already has an open pipeline entry for that event. Nothing was changed.

  • successboolean
  • errorstring
    Allowed values
    "VALIDATION_ERROR", "SCOPE_REQUIRED", "ORG_WIDE_TOKEN_REQUIRED", "FORBIDDEN", "NOT_FOUND", "CONFLICT", "QUOTA_EXCEEDED"
  • codestring

    A more specific reason: exists, read_only, platform_customer.

  • messagestringrequired
  • contactCrmContact

    With code: exists: the contact that has the email.

    Show child attributes
    • idstring
    • first_namestring
    • last_namestring | null
    • namestring
    • emailstring<email>
    • companystring | null
    • titlestring | null

      Job title.

    • avatar_urlstring | null
    • typesstring[]
      Allowed values
      "speaker", "sme", "influencer", "exhibitor", "sponsor"
    • tagsCrmTag[]
      Show child attributes
      • idstring
      • namestring
    • events_countinteger
    • sessions_countinteger
    • last_activity_atstring<date-time> | null
    • activeboolean

      An active contact in the last 365 days.

    • sourcestring | null

      Where the contact came from.

    • created_atstring<date-time>
    • hrefstring

      The contact in Sessionboard CRM.

    • stageobject | null

      The contact's pipeline stage; null when not in the pipeline.

      Show child attributes
      • idstring
      • labelstring

429

The token's request limit (100 requests per 15 minutes by default) or, for writes, its daily write quota. Wait Retry-After seconds.

  • Retry-Afterintegerheader

    Seconds to wait before retrying.

Response examples

{
"success": true,
"payload": {
"id": "<string>",
"title": "<string>",
"status": "created",
"source": "<string>",
"contact": {
"id": "<string>",
"name": "<string>",
"email": "jane@example.com"
},
"template": {
"id": "<string>",
"name": "<string>"
},
"signer_email": "jane@example.com",
"has_pdf": true,
"sent_at": "2026-01-15T09:30:00Z",
"signed_at": "2026-01-15T09:30:00Z",
"voided_at": "2026-01-15T09:30:00Z",
"updated_at": "2026-01-15T09:30:00Z"
}
}