# Update draft journal entry

`PUT /v1/journal-entries/{id}`

Changes a draft; only the fields you send change. `lines` replaces all lines, and lines that do not sum to exactly zero return 400 `validation_error`. A draft reconciled with a bank line must keep its line on that bank account. Booked and canceled entries cannot be changed here.

Returns 409 when the entry is not a draft, when Numina's bookkeeping agent is working on it, when you send `lines` for a foreign-currency draft, or when you send an `attachment_id` and the entry is linked to an invoice, already has a different document, or the document is already on another entry.

**Scopes:** any of `journal:write`, `write:draft`, `write:ledger`

## Request

```bash
curl -X PUT https://api.numina.app/v1/journal-entries/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer numi_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "date": "2024-01-15",
    "text": "Cash sale",
    "contact_id": "550e8400-e29b-41d4-a716-446655440000",
    "lines": [
      {
        "account_number": 3000,
        "amount": -1000,
        "vat_code": "U25"
      }
    ],
    "attachment_id": "550e8400-e29b-41d4-a716-446655440000"
  }'
```

## Path parameters

- `id` (string (uuid), required): Journal entry ID, as returned when it was created

## Body (`application/json`)

- `date` (string, optional): Transaction date in YYYY-MM-DD format (YYYY-MM-DD)
- `text` (string, optional): Transaction description (max 500 chars)
- `contact_id` (string (uuid), optional, nullable): Set the contact; null clears it
- `lines` (array of objects, optional): Replaces all lines. Send the full set, in DKK; it must sum to exactly zero.
  - `account_number` (integer, required): Account number in chart of accounts
  - `amount` (number, required): Signed amount in DKK: debit is positive, credit is negative. The lines must sum to exactly zero. With a `vat_code`, the amount includes VAT and the VAT is split out when the entry is booked.
  - `vat_code` (string, optional): VAT code (e.g., 'U25' for 25% sales VAT). Stored for later calculation during booking.
- `attachment_id` (string (uuid), optional, nullable): Put a document from POST /v1/attachments on this draft. To replace a document, take the current one off first. Null takes the current one off; the document itself stays.

## Response `200`

The updated draft

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "date": "2026-01-15",
  "text": "Invoice payment from customer",
  "status": "open",
  "contact_id": "550e8400-e29b-41d4-a716-446655440000",
  "created_at": "2026-01-15T10:30:00Z",
  "external_reference": "payroll-run-2026-01",
  "lines": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "account_number": 3000,
      "account_id": "550e8400-e29b-41d4-a716-446655440001",
      "account_name": "Revenue",
      "amount": -1000,
      "text": "Invoice payment",
      "vat_code": "U25",
      "currency_code": "DKK",
      "currency_rate": 1
    }
  ],
  "state": "draft",
  "attachment": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "file_name": "string",
    "status": "string",
    "attachment_number": 42
  }
}
```

## Errors

- `400` Bad Request - Invalid input or validation failed
- `401` Unauthorized - Invalid or missing authentication
- `403` Forbidden - Missing scope, or the company is archived
- `404` Not Found - The resource does not exist in this company
- `409` Conflict - The entry cannot take this change. Retry in a few minutes if the agent is the cause.
- `429` Too Many Requests - Rate limit exceeded
- `500` Internal Server Error

See https://developers.numina.app/errors.md for the error format.
