---
title: "Renew a contract"
method: POST
path: "/v1/accounts/{accountId}/documents/{documentId}/contract/renew"
tags: ["Contracts"]
---

# Renew a contract

`POST /v1/accounts/{accountId}/documents/{documentId}/contract/renew`

## Request

- Base URL: `https://api.assinafy.com.br`
- URL: `https://api.assinafy.com.br/v1/accounts/{accountId}/documents/{documentId}/contract/renew`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-Api-Key`

Starts the contract's next term: `end_date` moves by `renewal_term_months` (12 when unset), or to the `end_date` sent, which must be after the current one. A `value` sent replaces the current one. Reopens an expired contract; a terminated one returns `400`. Steps `term`, so the lifecycle alerts run again for the new term. Records a `document_contract_renewed` event. Needs a plan with contract tracking (`403` otherwise). The body names the `term` the renewal starts from (the contract's current one) or the `end_date` it renews to, so a renewal answered with a `5xx` error, or whose answer was lost, is safe to send again: the repeat is refused with `400`, as the contract is then in its next term and that date is no longer after the current one (or with `409`, when it sends the `updated_at` it read).

[Copy as Markdown](https://api.assinafy.com.br/v1/docs/markdown?method=post&path=%2Fv1%2Faccounts%2F%7BaccountId%7D%2Fdocuments%2F%7BdocumentId%7D%2Fcontract%2Frenew) [Open in ChatGPT](https://chatgpt.com/?q=Read%20the%20API%20documentation%20at%20https%3A%2F%2Fapi.assinafy.com.br%2Fv1%2Fdocs%2Fmarkdown%3Fmethod%3Dpost%26path%3D%252Fv1%252Faccounts%252F%257BaccountId%257D%252Fdocuments%252F%257BdocumentId%257D%252Fcontract%252Frenew%20and%20help%20me%20integrate%20this%20endpoint.) [Open in Claude](https://claude.ai/new?q=Read%20the%20API%20documentation%20at%20https%3A%2F%2Fapi.assinafy.com.br%2Fv1%2Fdocs%2Fmarkdown%3Fmethod%3Dpost%26path%3D%252Fv1%252Faccounts%252F%257BaccountId%257D%252Fdocuments%252F%257BdocumentId%257D%252Fcontract%252Frenew%20and%20help%20me%20integrate%20this%20endpoint.)

## Path parameters

- `accountId` string, required
- `documentId` string, required

## Request body

- object
  - `end_date` string, date, nullable: The new end date, after the current one. Absent, empty or `null`: the current end date plus the renewal term, stepped until it is in the future; `term` is then required.
  - `value` number, nullable: The new value; unchanged when not sent, cleared by `null`.
  - `term` integer: The term this renewal starts from, the contract's current `term`. Required unless `end_date` is sent; for a contract in another term the renewal is refused, so a repeated request never renews twice.
  - `updated_at` string, date-time: Optional precondition: the contract's `updated_at` as read. Changed since: `409`, nothing renewed.

## Response `200`

The renewed contract

- object: Standard success wrapper. Operations add their own `data`.
  - `status` integer: HTTP status code, mirrored in the body.
  - `message` string: Human-readable message; empty on success.
  - `data` DocumentContract: The contract terms tracked on a document.
    - `resource` string
    - `document_id` string
    - `status` 'draft' | 'active' | 'expired' | 'terminated'
    - `counterparty_name` string, nullable
    - `counterparty_taxpayer_id` string, nullable: CPF or CNPJ, digits only.
    - `value` number, nullable: Two decimal places at most.
    - `currency` string, nullable: ISO 4217 code; `BRL` when a value is sent without one.
    - `start_date` string, date, nullable
    - `end_date` string, date, nullable
    - `auto_renew` boolean
    - `renewal_term_months` integer, nullable
    - `notice_period_days` integer, nullable
    - `term` integer: Steps on every renewal, starting at 1.
    - `owner_id` string, nullable: ID of the workspace member who owns the contract. When the owner is no longer a member of the workspace (removed, left, or deleted with their account), the hourly run hands the contract to the first owner who is still an active member, or leaves it without one; an inactive member stays the owner. The contract's e-mails (renewal notice, expiring, expired, renewed) go to the first of the owner and the document's creator who is an active member, as that member's notification preferences allow.
    - `metadata` object, nullable: Up to 50 keys of your own, each holding text of at most 500 characters; `null` when there are none. A key ending in `_at` cannot hold a number: the API returns numbers under such keys as dates.
    - `external_references` object[]: IDs outside systems use for this contract, ordered by system and id.
      - `system` string
      - `id` string
    - `document` Document: A document and its current lifecycle state.
      - `resource` string: Present in single-resource responses.
      - `id` string
      - `account_id` string
      - `template_id` string, nullable
      - `name` string
      - `status` string: Status code — see GET /v1/documents/statuses.
      - `artifacts` object: Artifact download URLs keyed by name. Always `original`, plus `thumbnail` once one exists. A certificated document also carries `certificated`, `certificate-page` and `bundle`, and `pades` when it was signed with a digital certificate — the PAdES version holds the signers' ICP-Brasil signatures, which certification flattens out of the certificated PDF.
      - `is_closed` boolean
      - `signing_url` string
      - `verification_code` string, nullable: The code printed on the certificate page. Anyone can check it with `GET /v1/documents/{verification_code}/verify` or on `verification_url`. `null` until the document is `certificated`, and on documents certificated before verification codes existed.
      - `verification_url` string, uri, nullable: The public verification page for this document. `null` until the document is `certificated`.
      - `decline_reason` string, nullable
      - `declined_by` Signer: A signing party belonging to a workspace account.
        - `resource` string: Present in single-resource responses.
        - `id` string
        - `full_name` string
        - `email` string, email, nullable
        - `whatsapp_phone_number` string, nullable: E.164 format; normalized on save.
        - `government_id` string, nullable: Signer's normalized CPF (11 digits) or CNPJ (14 characters; may be alphanumeric).
        - `has_accepted_terms` boolean
      - `tags` object[]
        - `id` string
        - `name` string
      - `assignment` Assignment: A request for signers to sign a document.
        - `resource` string
        - `id` string
        - `document_id` string, nullable: The document this assignment belongs to. `null` only if the document was deleted.
        - `created_at` string, date-time
        - `sender_email` string, email, nullable: Email of the user who sent the document; null once that user has deleted their account.
        - `method` 'virtual' | 'collect'
        - `expires_at` string, date-time, nullable
        - `message` string, nullable
        - `signers` AssignmentSigner[]
          - `resource` string: Present in single-resource responses.
          - `id` string
          - `full_name` string
          - `email` string, email, nullable
          - `whatsapp_phone_number` string, nullable: E.164 format; normalized on save.
          - `government_id` string, nullable: Signer's normalized CPF (11 digits) or CNPJ (14 characters; may be alphanumeric).
          - `has_accepted_terms` boolean
          - `verification_method` string, nullable
          - `notification_methods` string[], nullable
          - `step` integer, nullable: Sequential signing step (defaults to 1).
          - `notified` boolean, nullable
          - `identity_verification_status` 'Pending' | 'InReview' | 'Approved' | 'Declined' | 'Expired' | 'Abandoned', nullable: Latest identity-document verification status; `InReview` means the account must decide it before the document can be certificated.
          - `completed` boolean, nullable: Only present in account-owner contexts.
          - `notification_history` NotificationHistoryEntry[], nullable: Per-channel delivery history for this signer (email + WhatsApp), most-recent send order.
            - `event` string
            - `status` 'sent' | 'failed'
            - `error_code` string, nullable
            - `error_message` string, nullable
            - `sent_at` string, date-time, nullable
            - `failed_at` string, date-time, nullable
        - `copy_receivers` object[]
        - `items` AssignmentItem[]
          - `id` string
          - `page` DocumentPage
            - `id` string
            - `number` integer
            - `height` integer
            - `width` integer
            - `download_url` string
          - `signer` object: Signer responsible for this item.
          - `field` object, nullable: Field definition associated with the item.
          - `display_settings` unknown
          - `value` unknown
          - `completed` boolean
        - `summary` AssignmentSummary
          - `signer_count` integer
          - `completed_count` integer
          - `signers` object[]
        - `signing_urls` SigningUrl[]
          - `signer_id` string
          - `url` string
      - `pages` DocumentPage[]: The document's pages. Included on the same responses as `assignment`, and also on the upload response.
        - `id` string
        - `number` integer
        - `height` integer
        - `width` integer
        - `download_url` string
      - `has_contract` boolean: Only on `GET /v1/documents/{documentId}` read by the workspace, while the environment has contract tracking on: not with a signer's access code, not in document lists or webhooks, and left out when the lookup fails, so a missing key means unknown. Whether `GET /v1/accounts/{accountId}/documents/{documentId}/contract` answers with contract terms, the document's own or those of a contract it amends whose document still exists, so a page can lay out the contract section before reading it.
      - `created_at` string, date-time
      - `updated_at` string, date-time
    - `amendments` DocumentContractAmendment[]: Only on the single-contract read: the documents that amend, renew or terminate this contract, the applied ones first by `number`, then the pending ones.
      - `resource` string
      - `document_id` string: This document, the instrument.
      - `document_name` string: This document's name.
      - `parent_document_id` string: The contract document whose terms change.
      - `relation_type` 'amendment' | 'renewal' | 'termination'
      - `number` integer, nullable: Position among the parent's applied amendments by signing date; `null` while pending.
      - `status` 'pending' | 'applied': `applied` once the delta moved the parent's terms.
      - `document_status` string: This document's own status, so a declined, cancelled or expired instrument shows as such. An instrument applies only while its document is `certificated`: one whose document reads `failed` after it was signed waits, with no `apply_error`, until it is certificated again, and then applies in its place in the signing order.
      - `apply_error` string, nullable: Why a signed instrument has not applied yet, retried every hour: the workspace's plan does not include contract tracking (it applies on the first run after the plan returns), the parent would not take the delta, an instrument signed before this one has not applied yet, one signed after it has already applied (this one then stays blocked: unlink it, and record what it still changes on a new instrument), or an unexpected failure.
      - `currency` string, nullable: The currency of the amounts in `terms` and `changes`. Once applied, the contract's currency at that moment, kept whatever the contract moves to later. While pending (and for an instrument applied before this was kept), the one this instrument moves the contract to, otherwise the contract's. `null` when neither has one.
      - `terms` object, nullable: The delta: only the terms this instrument changes; `null` when it changes none (a termination on the day it is signed).
      - `changes` object, nullable: Every parent field the roll-up moves, as `{from, to}`: a preview while pending, the record once applied; `null` when it moves none.
      - `applied_at` string, date-time, nullable
      - `created_at` string, date-time
      - `updated_at` string, date-time
    - `created_at` string, date-time
    - `updated_at` string, date-time

## Other responses

- `400`: The request breaks a contract rule. `errors` has one entry per problem found: the `field` as sent (`null` when the request as a whole is refused), a stable `code` to translate, and the `message` in the platform's language; `message` at the top is the first entry's. The contract's own rules on the terms, and the external references' items, report every field that breaks one, an entry per field (its first problem); the other checks (the body, its fields, the contract's state, a renewal's or a link's conditions) stop at the first problem they find. | Code | Field | Refused when | |------|-------|--------------| | `InvalidBody` | — | The body is not a JSON object (a list, a bare value), or a `PUT` of contract terms sends no attribute. | | `UnknownField` | the attribute | The endpoint does not take the attribute; one entry per attribute. | | `NotSingleValue` | the attribute | On a `PUT` of contract terms, a list sent for a term that takes one value (every term but `metadata` and `external_references`). On a link, the same list answers the term's own code. | | `Required` | `parent_document_id`, `relation_type`, `external_references[i].system`, `external_references[i].id` | A first link without `parent_document_id` (a pending link that was removed meanwhile) or `relation_type`; an `external_references` item without `system` or `id` (`i` is its place in the list sent, from 0). | | `Invalid` | the field | The value is not of the field's type or form: `status` not one of the four; `currency` not three letters; `auto_renew` not a boolean; `owner_id` not a user id; `value` not a number; `counterparty_name` holding HTML; `metadata` not an object; `external_references` not a list, an item's `system` (`external_references[i].system`) with characters other than letters, digits, `_`, `-` and `.`, or its `id` (`external_references[i].id`) with an emoji or another 4-byte character; `parent_document_id` not text; `relation_type` not `amendment`, `renewal` or `termination`; `term` not a whole number from 1; `reason` not text. On the list: a filter sent as a list, a `status` not one of the four, `ending_within_days` not a whole number. | | `TooSmall`, `TooBig` | the field | `value` below 0 or above 9999999999999.99; `renewal_term_months` outside 1 to 600; `notice_period_days` (and the list's `ending_within_days`) outside 0 to 3650. | | `TooLong` | the field | `counterparty_name` over 255 characters, counting each emoji as stored (several characters); `counterparty_taxpayer_id` over 20; `reason` over 500; `external_references[i].system` over 64 or `external_references[i].id` over 255. | | `TooMany` | `external_references` | More than 20 items. | | `TooManyDecimals` | `value` | More than two decimal places. | | `InvalidDate` | `start_date`, `end_date`, `updated_at`; the list's `end_date_from`, `end_date_to` | Not a date as `YYYY-MM-DD` (an impossible one such as `2026-02-30` included); `updated_at` not a date and time as the API writes it (`2026-10-23T12:00:00Z`, or with an offset). | | `DateTooEarly` | `start_date`, `end_date` | Before the year 1000. | | `DateTooLate` | `end_date` | A renewal by the term would pass 9999-12-31. | | `EndBeforeStart` | `end_date` | Before `start_date`. | | `InvalidTaxpayerId` | `counterparty_taxpayer_id` | Not a valid CPF or CNPJ (formatted or not). | | `NotAMember` | `owner_id` | Not an active member of the workspace. | | `TooManyKeys` | `metadata` | More than 50 keys. | | `InvalidKey` | `metadata` | A key that is not 1 to 40 letters, digits, `_`, `-` or `.`. | | `InvalidValue` | `metadata` | A value that is not plain text of at most 500 characters. | | `NumberUnderDateKey` | `metadata` | A number under a key ending in `_at`, or `stuck_since`, which the API would return as a date. | | `ListKeys` | `metadata` | Keys `0`, `1`, `2`…, which would read back as a list. | | `DuplicateReference` | `external_references` | Two items the database takes for one (accents, `ß` and `ss`); items equal case aside are merged, not refused. | | `StatusNotSettable` | `status` | A tracked contract sent `expired` or `terminated`, or a closed one sent `draft` or `active`: a contract is closed by terminating it and reopened by renewing it. | | `CannotReturnToDraft` | `status` | An `active` contract sent `draft`. | | `ExpiredNeedsPastEndDate` | `end_date` | New terms with status `expired` and no `end_date` before today. | | `TerminatedNeedsEndDate` | `end_date` | New terms with status `terminated` and no `end_date`. | | `UnsignableDocument` | — | New terms, or a first link, on a cancelled, declined or expired document. Terms or a link already on one stay editable. | | `DocumentIsAmendment` | — | Terms of its own for a document linked as an amendment: its terms are the changes it makes. | | `DocumentHasOwnTerms` | — | A link for a document that tracks a contract of its own: a document is a contract or an amendment, never both. | | `ParentHasNoTerms` | `parent_document_id` | The parent named has no contract terms, nor amends a contract that has. | | `ParentTerminated` | `parent_document_id` | The parent contract is terminated. | | `NoTermChanged` | — | An `amendment` that changes no term, also by dropping its last one. A `renewal` or `termination` may change none. | | `TermNotAllowed` | the term | A term the relation type cannot change: a `renewal` changes only `end_date` and `value`, a `termination` only `end_date`. | | `AmendmentApplied` | — | The amendment applied when its document was signed and can no longer change. | | `TermOrEndDateRequired` | — | A renewal sends neither `term` nor `end_date`. | | `TermMismatch` | `term` | Not the contract's current term: the renewal already happened. | | `ContractTerminated` | — | A renewal of a terminated contract. | | `EndDateRequired` | `end_date` | A renewal by the term, or a `renewal` link without `end_date`, of a contract without an end date. | | `EndDateNotAfterCurrent` | `end_date` | A renewal, or a `renewal` link, to a date not after the current end date. | | `AlreadyTerminated` | — | A termination of a contract already terminated. | A body that is not valid JSON is refused before it reaches these endpoints, with the platform's `400` and no `errors`. A link is also checked against what applying it today would give the parent, so a delta the contract would refuse comes back with the contract's own codes.
- `401`: Missing or invalid credentials.
- `403`: The workspace's plan does not include contract tracking.
- `404`: The document is not in the workspace (`Document not found.`), or carries no contract terms (on a read: neither its own nor those of a contract it amends whose document still exists). Only the second has a `code`, `NoContractTerms`, so a document without terms can be told from one that is not there.
- `409`: The write sent the `updated_at` it read the contract (or the amendment link) with, and the contract changed since: by another user, an integration or the hourly run. Nothing was written. Read it again, check the change still applies, and send it with the new `updated_at`.
- `500`: Unexpected server error.

## Changes

- **2026-10-28** `3672991376b6`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/assinafy/apis/assinafy-api-reference/changes/v1/accounts/:accountId/documents/:documentId/contract/renew/post.md)

---

[API](https://skmtc.dev/assinafy/apis/assinafy-api-reference.md) - [All operations](https://skmtc.dev/assinafy/apis/assinafy-api-reference/llms.txt) - [OpenAPI document](https://skmtc.dev/assinafy/apis/assinafy-api-reference/revisions/3672991376b6?raw)
