# Update counterparty

Update fields on a counterparty.

Partial update. Send only the fields you want to change. At least one updatable field is required. Country values are normalised to ISO 3166-1 alpha-2. payment_terms_days must be an integer between 0 and 365.


- HTTP method: `PATCH`
- Path: `/api/v1/counterparties/:code`
- URL: `https://api.invunion.com/api/v1/counterparties/:code`
- Required scope: `counterparties:write`
- HTML docs: https://www.invunion.com/knowledge-base/api/update-counterparty/
- Markdown docs: https://www.invunion.com/knowledge-base/api/update-counterparty.md

## Path parameters

| Name | Type | Required | Description | Allowed values | Example |
| --- | --- | --- | --- | --- | --- |
| `code` | string, max 50 | required | Counterparty code (`account_code`). |  | `CPT-042` |


## Body parameters

| Name | Type | Required | Description | Allowed values | Example |
| --- | --- | --- | --- | --- | --- |
| `name_original` | string, max 255 | optional | Legal or source name. At least one body field is required. |  | `Leones Cars` |
| `name_display` | string, max 255 | optional | Display name shown in the product. Defaults to empty when omitted. |  | `Leones Cars` |
| `account_code` | string, max 50 | optional | Your account code. Unique per tenant. If omitted, Invunion assigns CPT-NNN. |  | `CPT-042` |
| `category` | string, max 50 | optional | Legal form of the counterparty. Default professional. | `individual`, `professional`, `governmental` |  |
| `payment_terms_days` | integer | optional | Payment terms in days, 0 to 365. If omitted, tenant default applies. |  | `30` |
| `is_supplier` | boolean | optional | Supplier role. Default false. | `true`, `false` |  |
| `is_client` | boolean | optional | Client role. Default true on create. | `true`, `false` |  |
| `is_partner` | boolean | optional | Partner role. Default false. | `true`, `false` |  |
| `is_payer` | boolean | optional | Payer role. Default false. | `true`, `false` |  |
| `is_internal` | boolean | optional | Internal entity. Default false. | `true`, `false` |  |
| `is_employee` | boolean | optional | Employee. Default false. | `true`, `false` |  |
| `external_reference` | string, max 255 | optional | External reference. Your ERP or billing customer id. Used for identity lookup. |  | `ERP-1842` |
| `vat_number` | string, max 50 | optional | VAT number. Used for identity lookup on import. |  | `FR12345678901` |
| `registration_number` | string, max 100 | optional | National ID (SIREN, company number, and similar). |  | `123456789` |
| `electronic_address` | string, max 255 | optional | E-invoicing address (Peppol and similar). |  | `0208:123456789` |
| `address` | string, no maximum | optional | Street address. |  | `12 Grove Street` |
| `city` | string, max 255 | optional | City. |  | `Lyon` |
| `postal_code` | string, max 20 | optional | Postal code. |  | `69001` |
| `country` | string, no maximum | optional | Country name or ISO 3166-1 alpha-2 code. Stored as alpha-2. Invalid values return 400 on create. |  | `FR` |
| `email` | string, no maximum | optional | Contact email. |  | `carl@leonescars.fr` |
| `phone` | string, max 50 | optional | Phone number. |  | `+33472000000` |
| `analytic_1` | string, max 100 | optional | Analytic axis 1. |  | `SALES-EU` |
| `analytic_2` | string, max 100 | optional | Analytic axis 2. |  | `CHANNEL-DIRECT` |
| `metadata` | object | optional | JSON object. At most 32 keys, nested depth 3, 8 KB serialized, and 64-character key names. Keys __proto__, constructor, and prototype are rejected. |  | `{"erp_id":"C-1842"}` |

## Errors

| Error | HTTP code | Description |
| --- | --- | --- |
| `Missing Bearer token` | `401` | The Authorization header is missing or is not a Bearer token. |
| `Invalid or revoked API key` | `401` | The API key is unknown, malformed, expired, or has been revoked. |
| `API key is missing scope counterparties:write` | `403` | The key does not include counterparties:write. A write scope does not imply the matching read scope. |
| `Too many requests, please try again later` | `429` | Wait and retry. The Retry-After header is the number of seconds to wait. |
| `No fields to update` | `400` | The body did not contain any updatable field. |
| `Invalid country` | `400` | country could not be normalised to an ISO 3166-1 alpha-2 code. |
| `payment_terms_days must be an integer between 0 and 365` | `400` | payment_terms_days is missing, not an integer, or out of range. |
| `Counterparty not found` | `404` | No counterparty with this code exists in the authenticated tenant. |
| `Internal server error` | `500` | Unexpected server error. The JSON body includes correlationId. Retry with backoff. |

## Request (curl)

```bash
curl --request PATCH \
  --url https://api.invunion.com/api/v1/counterparties/CPT-042 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer uk_live_YOUR_API_KEY' \
  --header 'content-type: application/json' \
  --data '{
  "name_display": "Leones Cars Lyon",
  "payment_terms_days": 45,
  "is_payer": true
}'
```

## Request (Python)

```python
import requests

url = "https://api.invunion.com/api/v1/counterparties/CPT-042"
headers = {
    "Accept": "application/json",
    "Authorization": "Bearer uk_live_YOUR_API_KEY",
    "Content-Type": "application/json",
}
payload = {
    "name_display": "Leones Cars Lyon",
    "payment_terms_days": 45,
    "is_payer": True
}
response = requests.patch(url, json=payload, headers=headers)
print(response.json())
```

## Request (Ruby)

```ruby
require 'net/http'
require 'json'
require 'uri'

uri = URI("https://api.invunion.com/api/v1/counterparties/CPT-042")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(uri)
request['Accept'] = 'application/json'
request['Authorization'] = 'Bearer uk_live_YOUR_API_KEY'
request['Content-Type'] = 'application/json'
request.body = "{\n  \"name_display\": \"Leones Cars Lyon\",\n  \"payment_terms_days\": 45,\n  \"is_payer\": true\n}"
response = http.request(request)
puts response.body
```

## Request (JavaScript)

```javascript
const response = await fetch("https://api.invunion.com/api/v1/counterparties/CPT-042", {
  method: "PATCH",
  headers: {
    "Accept": "application/json",
    "Authorization": "Bearer uk_live_YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
  "name_display": "Leones Cars Lyon",
  "payment_terms_days": 45,
  "is_payer": true
}),
});
const data = await response.json();
```

## Request (Go)

```go
package main

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
)

func main() {
	payload := []byte(`{
  "name_display": "Leones Cars Lyon",
  "payment_terms_days": 45,
  "is_payer": true
}`)
	req, err := http.NewRequest("PATCH", "https://api.invunion.com/api/v1/counterparties/CPT-042", bytes.NewBuffer(payload))
	if err != nil {
		panic(err)
	}
	req.Header.Set("Accept", "application/json")
	req.Header.Set("Authorization", "Bearer uk_live_YOUR_API_KEY")
	req.Header.Set("Content-Type", "application/json")
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	body, _ := io.ReadAll(resp.Body)
	fmt.Println(string(body))
}
```

## Request (Node)

```javascript
const response = await fetch("https://api.invunion.com/api/v1/counterparties/CPT-042", {
  method: "PATCH",
  headers: {
    "Accept": "application/json",
    "Authorization": "Bearer uk_live_YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
  "name_display": "Leones Cars Lyon",
  "payment_terms_days": 45,
  "is_payer": true
}),
});
console.log(await response.json());
```

## Success (200)

```json
{
  "success": true,
  "data": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "tenant_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "name_original": "Leones Cars",
    "name_display": "Leones Cars Lyon",
    "account_code": "CPT-042",
    "category": "professional",
    "payment_terms_days": 45,
    "is_supplier": false,
    "is_client": true,
    "is_partner": false,
    "is_payer": true,
    "is_internal": false,
    "is_employee": false,
    "external_reference": "ERP-1842",
    "vat_number": "FR12345678901",
    "registration_number": "123456789",
    "electronic_address": "0208:123456789",
    "address": "12 Grove Street",
    "city": "Lyon",
    "postal_code": "69001",
    "country": "FR",
    "email": "carl@leonescars.fr",
    "phone": "+33472000000",
    "analytic_1": "SALES-EU",
    "analytic_2": "CHANNEL-DIRECT",
    "status": "up_to_date",
    "payer_score": 88,
    "payer_score_category": "good",
    "payment_score": 92,
    "avg_payment_days": 18,
    "total_invoiced": "12500.00",
    "total_revenue": 12500,
    "total_paid": "9800.00",
    "last_invoice_date": "2026-09-01",
    "last_payment_date": "2026-09-12",
    "invoice_count": 14,
    "outstanding_credit": "0.00",
    "unmatched_invoices_count": 2,
    "unmatched_transactions_count": 1,
    "is_system": false,
    "created_at": "2026-03-04T12:40:56.656Z",
    "updated_at": "2026-09-12T08:15:22.110Z",
    "metadata": {
      "erp_id": "C-1842"
    }
  },
  "message": "Counterparty updated successfully"
}
```
