Update Card Transaction
Updates editable fields on a credit card transaction, identified by transactionId.
Use this endpoint to enrich expenses in your reconciliation flow or ERP — for example, by recording purchase context, reconciling the transaction, or classifying it by category.
Editable fields today:
notes— transaction notes (max 1000 characters). Send an empty string ("") to clear.isConciled— marks the transaction as reconciled. Onlytrueis accepted: reconciling cannot be undone once applied.categoryId— numeric category ID.costCenterId— UUID of the cost center (use theidfield from GET /cost-centers/v1/cost-centers).
Rules:
transactionIdmust be the transactionidfrom the statement (GET /statements/v1/credit-card) — a ULID (e.g.01JB4M8WQ2YX5KN7RT9HF3DE6C), not a UUID.- At least one field must be provided in the body.
- Sending
isConciled: falsereturns 400 Bad Request. - A
categoryIdorcostCenterIdthat doesn't exist for the company returns 400 Bad Request. - When the transaction can't be reconciled, the API returns 409 Conflict.
- On success, the API returns 204 No Content (no body).
Example:
curl -X PATCH https://api-sandbox.contasimples.com/statements/v1/credit-card/01JB4M8WQ2YX5KN7RT9HF3DE6C \
-H "Authorization: Bearer {TOKEN}" \
-H "Content-Type: application/json" \
-d '{"notes":"Lunch with Acme client","isConciled":true,"categoryId":1146}'
curl -X PATCH "https://api-sandbox.contasimples.com/statements/v1/credit-card/01JB4M8WQ2YX5KN7RT9HF3DE6C" \
-H "Content-Type: application/json" \
-H "Signature-Input: example_string" \
-H "Signature: example_string" \
-H "Content-Digest: example_string" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-d '{
"notes": "Lunch with Acme client — sales meeting 2025-05-25",
"isConciled": true,
"categoryId": 1146,
"costCenterId": "a02f8f63-8b1b-4328-9d7d-0d2e351b8118"
}'
import requests
import json
url = "https://api-sandbox.contasimples.com/statements/v1/credit-card/01JB4M8WQ2YX5KN7RT9HF3DE6C"
headers = {
"Content-Type": "application/json",
"Signature-Input": "example_string",
"Signature": "example_string",
"Content-Digest": "example_string",
"Authorization": "Bearer YOUR_API_TOKEN"
}
data = {
"notes": "Lunch with Acme client — sales meeting 2025-05-25",
"isConciled": true,
"categoryId": 1146,
"costCenterId": "a02f8f63-8b1b-4328-9d7d-0d2e351b8118"
}
response = requests.patch(url, headers=headers, json=data)
print(response.json())
const response = await fetch("https://api-sandbox.contasimples.com/statements/v1/credit-card/01JB4M8WQ2YX5KN7RT9HF3DE6C", {
method: "PATCH",
headers: {
"Content-Type": "application/json",
"Signature-Input": "example_string",
"Signature": "example_string",
"Content-Digest": "example_string",
"Authorization": "Bearer YOUR_API_TOKEN"
},
body: JSON.stringify({
"notes": "Lunch with Acme client — sales meeting 2025-05-25",
"isConciled": true,
"categoryId": 1146,
"costCenterId": "a02f8f63-8b1b-4328-9d7d-0d2e351b8118"
})
});
const data = await response.json();
console.log(data);
package main
import (
"fmt"
"net/http"
"bytes"
"encoding/json"
)
func main() {
data := []byte(`{
"notes": "Lunch with Acme client — sales meeting 2025-05-25",
"isConciled": true,
"categoryId": 1146,
"costCenterId": "a02f8f63-8b1b-4328-9d7d-0d2e351b8118"
}`)
req, err := http.NewRequest("PATCH", "https://api-sandbox.contasimples.com/statements/v1/credit-card/01JB4M8WQ2YX5KN7RT9HF3DE6C", bytes.NewBuffer(data))
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Signature-Input", "example_string")
req.Header.Set("Signature", "example_string")
req.Header.Set("Content-Digest", "example_string")
req.Header.Set("Authorization", "Bearer YOUR_API_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("Response Status:", resp.Status)
}
require 'net/http'
require 'json'
uri = URI('https://api-sandbox.contasimples.com/statements/v1/credit-card/01JB4M8WQ2YX5KN7RT9HF3DE6C')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(uri)
request['Content-Type'] = 'application/json'
request['Signature-Input'] = 'example_string'
request['Signature'] = 'example_string'
request['Content-Digest'] = 'example_string'
request['Authorization'] = 'Bearer YOUR_API_TOKEN'
request.body = '{
"notes": "Lunch with Acme client — sales meeting 2025-05-25",
"isConciled": true,
"categoryId": 1146,
"costCenterId": "a02f8f63-8b1b-4328-9d7d-0d2e351b8118"
}'
response = http.request(request)
puts response.body
{}
{
"error": "Bad Request",
"message": "The request contains invalid parameters or malformed data",
"code": 400,
"requestId": "123e4567-e89b-12d3-a456-426614174000",
"details": [
"isConciled only accepts true — unmarking a transaction as reconciled is no longer supported"
]
}
{
"error": "Unauthorized",
"message": "Authentication required. Please provide a valid API token",
"code": 401
}
{
"error": "Forbidden",
"message": "The request is not allowed for the current credentials",
"code": 403,
"details": {
"requiredScope": "listCategories"
},
"requestId": "123e4567-e89b-12d3-a456-426614174000"
}
{
"error": "Not Found",
"message": "The requested resource was not found",
"code": 404
}
{
"error": "Conflict",
"message": "The request conflicts with the current state of the resource",
"code": 409,
"requestId": "123e4567-e89b-12d3-a456-426614174000"
}
{
"error": "Internal Server Error",
"message": "An unexpected error occurred on the server",
"code": 500,
"requestId": "req_1234567890"
}
/statements/v1/credit-card/{transactionId}Target server for requests. Edit to use your own host.
Bearer token from OAuth 2.0 client credentials. Format: Bearer TOKEN
Bearer TOKENTransaction ID on the statement (ULID) — use the id field from GET /statements/v1/credit-card (e.g. 01JB4M8WQ2YX5KN7RT9HF3DE6C).
The media type of the request body
What was signed and the signature parameters, in the RFC 9421 format. A credential with a public key must send it on every call, reads included, or the request is refused with 401. The signature covers the @method, @path, and @query components, and also content-digest when there is a body. created and alg are required, and created is valid for 300 seconds. The full format, with examples, is in Request Signing.
The signature of the base defined by RFC 9421, in base64, between : and under the same label used in Signature-Input, for example sig=:SGVsbG8gd29ybGQ=:. It always goes together with Signature-Input.
Hash of the request body in the RFC 9530 format, with sha-256 or sha-512, for example sha-256=:X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=:. It is required when the request has a body and the credential has a public key, and in that case Signature-Input must include the content-digest component.
Transaction notes. Send an empty string ("") to clear.
Marks the transaction as reconciled. Only true is accepted — reconciling cannot be undone once applied.
Category ID — use the id field from GET /categories/v1/categories.
UUID of the cost center — use the id field from GET /cost-centers/v1/cost-centers.
Request Preview
Response
Response will appear here after sending the request
Authentication
Bearer token. Bearer token from OAuth 2.0 client credentials. Format: Bearer TOKEN
Path Parameters
Transaction ID on the statement (ULID) — use the id field from GET /statements/v1/credit-card (e.g. 01JB4M8WQ2YX5KN7RT9HF3DE6C).
01JB4M8WQ2YX5KN7RT9HF3DE6CHeaders
What was signed and the signature parameters, in the RFC 9421 format. A credential with a public key must send it on every call, reads included, or the request is refused with 401. The signature covers the @method, @path, and @query components, and also content-digest when there is a body. created and alg are required, and created is valid for 300 seconds. The full format, with examples, is in Request Signing.
The signature of the base defined by RFC 9421, in base64, between : and under the same label used in Signature-Input, for example sig=:SGVsbG8gd29ybGQ=:. It always goes together with Signature-Input.
Hash of the request body in the RFC 9530 format, with sha-256 or sha-512, for example sha-256=:X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=:. It is required when the request has a body and the credential has a public key, and in that case Signature-Input must include the content-digest component.
Body
Transaction notes. Send an empty string ("") to clear.
Lunch with Acme client — sales meeting 2025-05-25Marks the transaction as reconciled. Only true is accepted — reconciling cannot be undone once applied.
trueUUID of the cost center — use the id field from GET /cost-centers/v1/cost-centers.
a02f8f63-8b1b-4328-9d7d-0d2e351b8118