> ## Documentation Index
> Fetch the complete documentation index at: https://docs.alforse.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Contracts

> Create, list, update, and manage the full lifecycle of a contract.

All endpoints on this page require a tenant bearer token. See
[Roles & Permissions](/concepts/roles-and-permissions) for what each `@Perm` module/level means.

## List contracts

`GET /contracts` · requires `contract_view` (view)

<ParamField query="page" type="integer" default="1" />

<ParamField query="pageSize" type="integer" default="20">Max 200.</ParamField>
<ParamField query="q" type="string">Free-text search.</ParamField>
<ParamField query="type" type="string">`sale` | `lease`</ParamField>
<ParamField query="typeCode" type="string">Custom contract type code, if configured.</ParamField>
<ParamField query="status" type="string">`in_progress` | `completed`</ParamField>

<ParamField query="statusCode" type="string" />

<ParamField query="payment" type="string">`unpaid` | `partial` | `paid`</ParamField>

<ParamField query="ownerId" type="string" />

<ParamField query="subjectId" type="string" />

<ParamField query="workflow" type="string">
  One of `draft`, `extracted`, `review`, `approved`, `signed`, `active`, `completed`, `archived`.
</ParamField>

<ParamField query="lifecycleStageCode" type="string" />

<ParamField query="overdue" type="boolean" />

<ParamField query="dueSoon" type="boolean" />

<ParamField query="sort" type="string" />

<ParamField query="order" type="string" default="asc">`asc` | `desc`</ParamField>

## Get a contract

`GET /contracts/:id` · requires `contract_view` (view)

## Create a contract

`POST /contracts` · requires `contract_edit` (edit)

<ParamField body="archiveCode" type="string" required />

<ParamField body="contractNo" type="string" required />

<ParamField body="projectName" type="string" required />

<ParamField body="type" type="string">`sale` | `lease`</ParamField>

<ParamField body="typeCode" type="string" />

<ParamField body="subjectId" type="string" required />

<ParamField body="partyA" type="string" required />

<ParamField body="partyB" type="string" required />

<ParamField body="equipmentName" type="string" required />

<ParamField body="equipmentModel" type="string" required />

<ParamField body="quantity" type="integer" required>Minimum 1.</ParamField>
<ParamField body="unitPrice" type="number" required>Minimum 0.</ParamField>
<ParamField body="totalAmount" type="number">Minimum 0.</ParamField>

<ParamField body="currencyCode" type="string" />

<ParamField body="paymentMethod" type="string" required />

<ParamField body="payeeAccount" type="string" />

<ParamField body="payeeBank" type="string" />

<ParamField body="deposit" type="number" />

<ParamField body="periodicRent" type="number" />

<ParamField body="paymentCycle" type="string" />

<ParamField body="signDate" type="string">ISO date.</ParamField>
<ParamField body="startDate" type="string" required>ISO date.</ParamField>
<ParamField body="endDate" type="string" required>ISO date.</ParamField>

<ParamField body="invoicePoints" type="integer" />

<ParamField body="contractAttachment" type="string">File reference.</ParamField>
<ParamField body="status" type="string">`in_progress` | `completed`</ParamField>

<ParamField body="statusCode" type="string" />

<ParamField body="ownerId" type="string" required />

<ParamField body="ownerSuperiorId" type="string" />

<ParamField body="remark" type="string" />

<ParamField body="dynamicFields" type="object">Custom field values keyed by field id.</ParamField>

<ParamField body="workflowStage" type="string" />

<ParamField body="lifecycleTemplateId" type="string" />

<ParamField body="lifecycleStageCode" type="string" />

<ParamField body="workflowAllowedRoles" type="string[]" />

<ParamField body="payments" type="array">
  Initial payment plan lines — see [Add a payment line](#add-a-payment-line) for the shape of
  each entry.
</ParamField>

<ParamField body="terms" type="array">See [Add a term note](#add-a-term-note).</ParamField>
<ParamField body="extraNotes" type="array">`{ label, value }[]`</ParamField>

```bash theme={null}
curl -X POST https://api.alforse.com/api/v1/contracts \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "archiveCode": "A-2026-001",
    "contractNo": "C-2026-001",
    "projectName": "Excavator lease — north yard",
    "subjectId": "sub_123",
    "partyA": "Acme Leasing",
    "partyB": "Northline Construction",
    "equipmentName": "Excavator",
    "equipmentModel": "CAT-320",
    "quantity": 1,
    "unitPrice": 250000,
    "paymentMethod": "bank_transfer",
    "startDate": "2026-08-01",
    "endDate": "2027-08-01",
    "ownerId": "usr_456"
  }'
```

## Update a contract

`PATCH /contracts/:id` · requires `contract_edit` (edit)

Same fields as create, all optional.

## Delete a contract

`DELETE /contracts/:id` · requires `contract_delete` (edit)

## Bulk operations

| Endpoint                          | Body                                            | Requires                 |
| --------------------------------- | ----------------------------------------------- | ------------------------ |
| `POST /contracts/bulk-delete`     | `{ ids: string[] }` (max 1000)                  | `contract_delete` (edit) |
| `POST /contracts/bulk-attachment` | `{ ids: string[], contractAttachment: string }` | `contract_edit` (edit)   |

## Import and export

| Endpoint                 | Body                                                                                                             | Requires               |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------- | ---------------------- |
| `POST /contracts/import` | `{ rows?: CreateContractDto[], xlsxBase64?, sheetName?, csv? }` — supply one of `rows`, `xlsxBase64`, or `csv`   | `contract_edit` (edit) |
| `GET /contracts/export`  | Same query params as [List](#list-contracts), plus `ids?: string[]` and `profile: "summary" \| "full"`           | `export` (edit)        |
| `POST /contracts/export` | Same fields as the `GET` variant, in the body — use this when your filter/id list is too long for a query string | `export` (edit)        |

Both export endpoints respond with `Content-Type: text/csv; charset=utf-8`.

## OCR extraction

| Endpoint                                     | Body                                                                                                                        | Requires               |
| -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ---------------------- |
| `POST /contracts/extract`                    | `{ contractId?, fileRef?, fileName?, text? }`                                                                               | `contract_edit` (edit) |
| `PATCH /contracts/extractions/:runId/review` | `{ fields: { fieldKey, status: "accepted" \| "overridden" \| "rejected", overrideValue? }[], applyToContract?, metadata? }` | `contract_edit` (edit) |

See [Contract Intake](/guides/contract-intake) for how this fits into the upload flow.

## Add a note

`POST /contracts/:id/notes` · requires `contract_edit` (edit)

<ParamField body="label" type="string" required />

<ParamField body="value" type="string" required />

## Add a term note

`POST /contracts/:id/terms` · requires `contract_edit` (edit)

<ParamField body="kind" type="string" required>
  `deposit` | `delivery` | `debug` | `payment` | `expiry` | `other`
</ParamField>

<ParamField body="title" type="string" required />

<ParamField body="date" type="string">ISO date.</ParamField>

<ParamField body="note" type="string" required />

## Add a payment line

`POST /contracts/:id/payments` · requires `payment_entry` (edit)

<ParamField body="period" type="string" required />

<ParamField body="dueDate" type="string" required>ISO date.</ParamField>
<ParamField body="amount" type="number" required>Minimum 0.</ParamField>

<ParamField body="currencyCode" type="string" />

<ParamField body="receivedAmount" type="number" />

<ParamField body="receivedDate" type="string" />

<ParamField body="method" type="string" />

<ParamField body="payerName" type="string" />

<ParamField body="receiptAccount" type="string" />

<ParamField body="bankSerialNo" type="string" />

<ParamField body="reconciliationStatus" type="string">`pending` | `matched` | `exception`</ParamField>

<ParamField body="reconciliationNote" type="string" />

<ParamField body="invoiceAmount" type="number" />

<ParamField body="invoiceDate" type="string" />

<ParamField body="invoiceNo" type="string" />

<ParamField body="invoiceAttachment" type="string" />

<ParamField body="proof" type="string" />

For updating a payment that already exists (rather than adding a new line), see
[Payments](/api-reference/payments).

## Fulfillment tasks

| Endpoint                                         | Body                                                                                             | Requires               |
| ------------------------------------------------ | ------------------------------------------------------------------------------------------------ | ---------------------- |
| `POST /contracts/:id/fulfillment-tasks`          | `{ code, title, kind?, status?, ownerId?, dueDate?, acceptanceStatus?, attachment?, metadata? }` | `contract_edit` (edit) |
| `PATCH /contracts/:id/fulfillment-tasks/:taskId` | Same fields, all optional                                                                        | `contract_edit` (edit) |

`status` is one of `pending`, `in_progress`, `completed`, `accepted`, `blocked`, `canceled`,
`overdue`.

## Add an invoice record

`POST /contracts/:id/invoices` · requires `invoice` (edit)

<ParamField body="receivablePlanId" type="string" />

<ParamField body="paymentRecordId" type="string" />

<ParamField body="invoiceNo" type="string" required />

<ParamField body="invoiceAmount" type="number" required>Minimum 0.</ParamField>

<ParamField body="invoiceDate" type="string" />

<ParamField body="status" type="string">`draft` | `issued` | `void` | `red_letter`</ParamField>

<ParamField body="attachment" type="string" />

<ParamField body="taxRate" type="number" />

<ParamField body="note" type="string" />
