Commerce Memory
Generated HTTP reference for the 12 operations the published OpenAPI document describes under commerce-memory.
Commerce Memory
This page is generated from the published OpenAPI document. It is complete with respect to that document and says nothing about surfaces the document does not describe yet. See what is generated here for what that means.
Base URL: https://api.codespar.dev
Every operation below requires a Bearer token. See Authentication.
GET /v1/commerce-memory/counterparties
https://api.codespar.dev/v1/commerce-memory/counterpartiesList this project's counterparties (deprecated path)
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
identifier | string | no | — |
identifier_kind | "cnpj" | "cpf" | "email" | "phone" | "wallet_address" | "other" | no | — |
kind | "supplier" | "customer" | "agent_peer" | no | — |
limit | integer | no | — |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
400 | object | invalid_query, with the validator's issue list under details.issues. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
counterparties | array of object | yes | — |
curl -X GET https://api.codespar.dev/v1/commerce-memory/counterparties \
-H "Authorization: Bearer $CODESPAR_API_KEY"const res = await fetch("https://api.codespar.dev/v1/commerce-memory/counterparties", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.CODESPAR_API_KEY}`,
},
});
const data = await res.json();{
"counterparties": [
{
"id": "obj_0000000000000000",
"kind": "supplier",
"name": "Example",
"identifier_kind": "cnpj",
"metadata": {},
"created_at": "2026-01-15T12:00:00.000Z",
"last_seen_at": "2026-01-15T12:00:00.000Z"
}
]
}POST /v1/commerce-memory/counterparties
https://api.codespar.dev/v1/commerce-memory/counterpartiesRegister a counterparty, or merge into the one already there (deprecated path)
Request body
| Field | Type | Required | Description |
|---|---|---|---|
identifier | string | no | Set it together with identifier_kind or omit both. One without the other is refused. |
identifier_kind | "cnpj" | "cpf" | "email" | "phone" | "wallet_address" | "other" | no | — |
kind | "supplier" | "customer" | "agent_peer" | yes | — |
metadata | object | no | — |
name | string | yes | — |
Responses
| Status | Body | Description |
|---|---|---|
201 | object | Created, or merged into the existing row. |
400 | object | invalid_body. details.issues carries the validator's own issue list, including the case where only one of identifier / identifier_kind was sent. |
Response 201
| Field | Type | Required | Description |
|---|---|---|---|
created_at | string (date-time) | yes | — |
id | string | yes | cp_ prefixed. |
identifier | string,null | yes | Null when the counterparty was registered without one. |
identifier_kind | "cnpj" | "cpf" | "email" | "phone" | "wallet_address" | "other" | yes | — |
kind | "supplier" | "customer" | "agent_peer" | yes | — |
last_seen_at | string (date-time) | yes | Bumped by a re-registration of the same identifier and by every interaction written against this counterparty. |
metadata | object | yes | — |
name | string | yes | — |
curl -X POST https://api.codespar.dev/v1/commerce-memory/counterparties \
-H "Authorization: Bearer $CODESPAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"kind": "supplier",
"name": "Example",
"identifier": "string",
"identifier_kind": "cnpj",
"metadata": {}
}'const res = await fetch("https://api.codespar.dev/v1/commerce-memory/counterparties", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CODESPAR_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"kind": "supplier",
"name": "Example",
"identifier": "string",
"identifier_kind": "cnpj",
"metadata": {}
}),
});
const data = await res.json();{
"id": "obj_0000000000000000",
"kind": "supplier",
"name": "Example",
"identifier_kind": "cnpj",
"metadata": {},
"created_at": "2026-01-15T12:00:00.000Z",
"last_seen_at": "2026-01-15T12:00:00.000Z"
}GET /v1/commerce-memory/counterparties/{id}
https://api.codespar.dev/v1/commerce-memory/counterparties/{id}Read one counterparty (deprecated path)
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | yes | cp_ prefixed. |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
404 | object | not_found, including for a counterparty outside the caller's project. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
created_at | string (date-time) | yes | — |
id | string | yes | cp_ prefixed. |
identifier | string,null | yes | Null when the counterparty was registered without one. |
identifier_kind | "cnpj" | "cpf" | "email" | "phone" | "wallet_address" | "other" | yes | — |
kind | "supplier" | "customer" | "agent_peer" | yes | — |
last_seen_at | string (date-time) | yes | Bumped by a re-registration of the same identifier and by every interaction written against this counterparty. |
metadata | object | yes | — |
name | string | yes | — |
curl -X GET https://api.codespar.dev/v1/commerce-memory/counterparties/{id} \
-H "Authorization: Bearer $CODESPAR_API_KEY"const res = await fetch("https://api.codespar.dev/v1/commerce-memory/counterparties/{id}", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.CODESPAR_API_KEY}`,
},
});
const data = await res.json();{
"id": "obj_0000000000000000",
"kind": "supplier",
"name": "Example",
"identifier_kind": "cnpj",
"metadata": {},
"created_at": "2026-01-15T12:00:00.000Z",
"last_seen_at": "2026-01-15T12:00:00.000Z"
}GET /v1/commerce-memory/insights/counterparty-summary
https://api.codespar.dev/v1/commerce-memory/insights/counterparty-summaryPer counterparty rollup over a window
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
kind | "supplier" | "customer" | "agent_peer" | no | — |
limit | integer | no | — |
since | string (date-time) | no | Inclusive lower bound on occurred_at. |
until | string (date-time) | no | Exclusive upper bound on occurred_at. |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
400 | object | invalid_query, with the validator's issue list under details.issues. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
rows | array of object | yes | — |
window | object | yes | The since and until of the request, echoed back, null when not supplied. |
curl -X GET https://api.codespar.dev/v1/commerce-memory/insights/counterparty-summary \
-H "Authorization: Bearer $CODESPAR_API_KEY"const res = await fetch("https://api.codespar.dev/v1/commerce-memory/insights/counterparty-summary", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.CODESPAR_API_KEY}`,
},
});
const data = await res.json();{
"window": {},
"rows": [
{
"counterparty_id": "counterparty_0000000000000000",
"name": "Example",
"kind": "supplier",
"identifier_kind": "cnpj",
"last_seen_at": "2026-01-15T12:00:00.000Z",
"interaction_count": 1,
"payment_count": 1,
"total_payment_minor": 1,
"currencies": [
"string"
]
}
]
}GET /v1/commerce-memory/insights/negotiation-stats
https://api.codespar.dev/v1/commerce-memory/insights/negotiation-statsNegotiation outcomes and average discount, grouped by item
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
item_ref | string | no | — |
since | string (date-time) | no | Inclusive lower bound on started_at. |
until | string (date-time) | no | Exclusive upper bound on started_at. |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
400 | object | invalid_query, with the validator's issue list under details.issues. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
item_ref | string,null | yes | The item_ref filter of the request, echoed back. |
rows | array of object | yes | — |
window | object | yes | The since and until of the request, echoed back, null when not supplied. |
curl -X GET https://api.codespar.dev/v1/commerce-memory/insights/negotiation-stats \
-H "Authorization: Bearer $CODESPAR_API_KEY"const res = await fetch("https://api.codespar.dev/v1/commerce-memory/insights/negotiation-stats", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.CODESPAR_API_KEY}`,
},
});
const data = await res.json();{
"window": {},
"rows": [
{
"outcome": "agreed",
"n": 0,
"currencies": [
"string"
],
"discount_sample_n": 1
}
]
}GET /v1/commerce-memory/insights/top-counterparties
https://api.codespar.dev/v1/commerce-memory/insights/top-counterpartiesCounterparties ranked by payment volume in a window
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
kind | "supplier" | "customer" | "agent_peer" | no | — |
limit | integer | no | — |
since | string (date-time) | no | Inclusive lower bound on occurred_at. |
until | string (date-time) | no | Exclusive upper bound on occurred_at. |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
400 | object | invalid_query, with the validator's issue list under details.issues. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
kind | "supplier" | "customer" | "agent_peer" | yes | The kind filter of the request, echoed back. |
rows | array of object | yes | — |
window | object | yes | The since and until of the request, echoed back, null when not supplied. |
curl -X GET https://api.codespar.dev/v1/commerce-memory/insights/top-counterparties \
-H "Authorization: Bearer $CODESPAR_API_KEY"const res = await fetch("https://api.codespar.dev/v1/commerce-memory/insights/top-counterparties", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.CODESPAR_API_KEY}`,
},
});
const data = await res.json();{
"window": {},
"kind": "supplier",
"rows": [
{
"counterparty_id": "counterparty_0000000000000000",
"name": "Example",
"kind": "supplier",
"payment_count": 1,
"total_payment_minor": 1
}
]
}GET /v1/commerce-memory/interactions
https://api.codespar.dev/v1/commerce-memory/interactionsList recorded interactions
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
counterparty_id | string | no | — |
kind | "quote" | "negotiation" | "order" | "invoice" | "payment" | "shipment" | "message" | "other" | no | — |
limit | integer | no | — |
since | string (date-time) | no | Inclusive lower bound on occurred_at. |
until | string (date-time) | no | Exclusive upper bound on occurred_at. |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
400 | object | invalid_query, with the validator's issue list under details.issues. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
interactions | array of object | yes | — |
curl -X GET https://api.codespar.dev/v1/commerce-memory/interactions \
-H "Authorization: Bearer $CODESPAR_API_KEY"const res = await fetch("https://api.codespar.dev/v1/commerce-memory/interactions", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.CODESPAR_API_KEY}`,
},
});
const data = await res.json();{
"interactions": [
{
"id": "obj_0000000000000000",
"counterparty_id": "counterparty_0000000000000000",
"kind": "quote",
"occurred_at": "2026-01-15T12:00:00.000Z",
"source": "agent_execute",
"metadata": {}
}
]
}POST /v1/commerce-memory/interactions
https://api.codespar.dev/v1/commerce-memory/interactionsRecord a commercial event against a counterparty
Request body
| Field | Type | Required | Description |
|---|---|---|---|
agent_id | string | no | — |
amount_minor | integer | no | Minor units. Set it together with currency or omit both. |
counterparty_id | string | yes | — |
currency | string | no | — |
kind | "quote" | "negotiation" | "order" | "invoice" | "payment" | "shipment" | "message" | "other" | yes | — |
metadata | object | no | — |
occurred_at | string (date-time) | no | Defaults to now. |
source | "agent_execute" | "webhook" | "manual" | "backfill" | no | — |
source_ref | string | no | The idempotency key, paired with source. Omit it and every post writes a new row. |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | Idempotent replay. (source, source_ref) already existed in this project; nothing was written and the stored row is returned. |
201 | object | Recorded. |
400 | object | invalid_body, with the validator's issue list under details.issues. |
404 | object | counterparty_not_found: the id does not belong to this org and project. |
500 | object | idempotent_lookup_failed. The insert hit the idempotency key but the conflicting row could not be read back afterwards. Nothing was written; the call is safe to retry. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
idempotent | true | yes | — |
interaction | object | yes | — |
curl -X POST https://api.codespar.dev/v1/commerce-memory/interactions \
-H "Authorization: Bearer $CODESPAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"counterparty_id": "counterparty_0000000000000000",
"kind": "quote",
"amount_minor": 1000,
"currency": "BRL",
"occurred_at": "2026-01-15T12:00:00.000Z",
"source": "agent_execute",
"source_ref": "string",
"agent_id": "agt_0000000000000000",
"metadata": {}
}'const res = await fetch("https://api.codespar.dev/v1/commerce-memory/interactions", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CODESPAR_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"counterparty_id": "counterparty_0000000000000000",
"kind": "quote",
"amount_minor": 1000,
"currency": "BRL",
"occurred_at": "2026-01-15T12:00:00.000Z",
"source": "agent_execute",
"source_ref": "string",
"agent_id": "agt_0000000000000000",
"metadata": {}
}),
});
const data = await res.json();{
"idempotent": true,
"interaction": {
"id": "obj_0000000000000000",
"counterparty_id": "counterparty_0000000000000000",
"kind": "quote",
"occurred_at": "2026-01-15T12:00:00.000Z",
"source": "agent_execute",
"metadata": {}
}
}GET /v1/commerce-memory/negotiations
https://api.codespar.dev/v1/commerce-memory/negotiationsList negotiations
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
counterparty_id | string | no | — |
item_ref | string | no | — |
limit | integer | no | — |
outcome | "agreed" | "declined" | "pending" | "expired" | no | — |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
400 | object | invalid_query, with the validator's issue list under details.issues. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
negotiations | array of object | yes | — |
curl -X GET https://api.codespar.dev/v1/commerce-memory/negotiations \
-H "Authorization: Bearer $CODESPAR_API_KEY"const res = await fetch("https://api.codespar.dev/v1/commerce-memory/negotiations", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.CODESPAR_API_KEY}`,
},
});
const data = await res.json();{
"negotiations": [
{
"id": "obj_0000000000000000",
"counterparty_id": "counterparty_0000000000000000",
"item": "string",
"currency": "BRL",
"rounds": 0,
"outcome": "agreed",
"started_at": "2026-01-15T12:00:00.000Z",
"metadata": {}
}
]
}POST /v1/commerce-memory/negotiations
https://api.codespar.dev/v1/commerce-memory/negotiationsRecord a price negotiation and its outcome
Request body
| Field | Type | Required | Description |
|---|---|---|---|
agent_id | string | no | — |
agreed_price_minor | integer | no | Minor units of currency. Required when outcome is agreed. |
closed_at | string (date-time) | no | Read only when outcome is terminal. Ignored while the outcome is pending. |
counterparty_id | string | yes | — |
currency | string | yes | — |
initial_price_minor | integer | no | Minor units of currency. |
item | string | yes | Free text description of what was negotiated. |
item_ref | string | no | Structured pointer (sku, contract id, supplier product code). It is the grouping key of the negotiation-stats rollup. |
metadata | object | no | — |
outcome | "agreed" | "declined" | "pending" | "expired" | no | Defaults to pending. |
rounds | integer | no | Defaults to 1. |
started_at | string (date-time) | no | Defaults to now. |
Responses
| Status | Body | Description |
|---|---|---|
201 | object | Recorded. |
400 | object | invalid_body, with the validator's issue list under details.issues. Includes the outcome: agreed without agreed_price_minor case. |
404 | object | counterparty_not_found: the id does not belong to this org and project. |
Response 201
| Field | Type | Required | Description |
|---|---|---|---|
agent_id | string,null | yes | — |
agreed_price_minor | integer,null | yes | Minor units of currency. |
closed_at | string,null (date-time) | yes | Null exactly when outcome is pending. |
counterparty_id | string | yes | — |
currency | string | yes | — |
id | string | yes | neg_ prefixed. |
initial_price_minor | integer,null | yes | Minor units of currency. |
item | string | yes | — |
item_ref | string,null | yes | — |
metadata | object | yes | — |
outcome | "agreed" | "declined" | "pending" | "expired" | yes | — |
rounds | integer | yes | — |
started_at | string (date-time) | yes | — |
curl -X POST https://api.codespar.dev/v1/commerce-memory/negotiations \
-H "Authorization: Bearer $CODESPAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"counterparty_id": "counterparty_0000000000000000",
"item": "string",
"item_ref": "string",
"initial_price_minor": 1,
"agreed_price_minor": 1,
"currency": "BRL",
"rounds": 0,
"outcome": "agreed",
"agent_id": "agt_0000000000000000",
"started_at": "2026-01-15T12:00:00.000Z",
"closed_at": "2026-01-15T12:00:00.000Z",
"metadata": {}
}'const res = await fetch("https://api.codespar.dev/v1/commerce-memory/negotiations", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CODESPAR_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"counterparty_id": "counterparty_0000000000000000",
"item": "string",
"item_ref": "string",
"initial_price_minor": 1,
"agreed_price_minor": 1,
"currency": "BRL",
"rounds": 0,
"outcome": "agreed",
"agent_id": "agt_0000000000000000",
"started_at": "2026-01-15T12:00:00.000Z",
"closed_at": "2026-01-15T12:00:00.000Z",
"metadata": {}
}),
});
const data = await res.json();{
"id": "obj_0000000000000000",
"counterparty_id": "counterparty_0000000000000000",
"item": "string",
"currency": "BRL",
"rounds": 0,
"outcome": "agreed",
"started_at": "2026-01-15T12:00:00.000Z",
"metadata": {}
}GET /v1/commerce-memory/preferences
https://api.codespar.dev/v1/commerce-memory/preferencesList preferences
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
counterparty_id | string | no | — |
limit | integer | no | — |
source | "explicit" | "derived" | "inherited" | no | — |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
400 | object | invalid_query, with the validator's issue list under details.issues. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
preferences | array of object | yes | — |
curl -X GET https://api.codespar.dev/v1/commerce-memory/preferences \
-H "Authorization: Bearer $CODESPAR_API_KEY"const res = await fetch("https://api.codespar.dev/v1/commerce-memory/preferences", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.CODESPAR_API_KEY}`,
},
});
const data = await res.json();{
"preferences": [
{
"id": "obj_0000000000000000",
"counterparty_id": "counterparty_0000000000000000",
"preference_key": "string",
"value": "string",
"confidence": 0,
"source": "explicit",
"created_at": "2026-01-15T12:00:00.000Z",
"updated_at": "2026-01-15T12:00:00.000Z",
"metadata": {}
}
]
}POST /v1/commerce-memory/preferences
https://api.codespar.dev/v1/commerce-memory/preferencesSet or update one preference on a counterparty
Request body
| Field | Type | Required | Description |
|---|---|---|---|
confidence | number | no | Defaults to 1. |
counterparty_id | string | yes | — |
metadata | object | no | — |
preference_key | string | yes | Lowercase ASCII, digits and underscore. The vocabulary is open: a new key needs no migration. |
source | "explicit" | "derived" | "inherited" | no | Defaults to explicit. |
value | — | no | Any JSON value. Send it. The validator is unknown, which in Zod accepts a body that omits the key, but the column behind it is NOT NULL, so a body without value is not a supported call. |
Responses
| Status | Body | Description |
|---|---|---|
201 | object | Created, or updated in place. |
400 | object | invalid_body, with the validator's issue list under details.issues. |
404 | object | counterparty_not_found: the id does not belong to this org and project. |
Response 201
| Field | Type | Required | Description |
|---|---|---|---|
confidence | number | yes | 0 to 1. 1 means an operator asserted it; below that it was derived. |
counterparty_id | string | yes | — |
created_at | string (date-time) | yes | — |
id | string | yes | pref_ prefixed. |
metadata | object | yes | — |
preference_key | string | yes | — |
source | "explicit" | "derived" | "inherited" | yes | — |
updated_at | string (date-time) | yes | — |
value | string | number | boolean | array of — | object | null | yes | Any JSON value. Always present. |
curl -X POST https://api.codespar.dev/v1/commerce-memory/preferences \
-H "Authorization: Bearer $CODESPAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"counterparty_id": "counterparty_0000000000000000",
"preference_key": "string",
"confidence": 0,
"source": "explicit",
"metadata": {}
}'const res = await fetch("https://api.codespar.dev/v1/commerce-memory/preferences", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CODESPAR_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"counterparty_id": "counterparty_0000000000000000",
"preference_key": "string",
"confidence": 0,
"source": "explicit",
"metadata": {}
}),
});
const data = await res.json();{
"id": "obj_0000000000000000",
"counterparty_id": "counterparty_0000000000000000",
"preference_key": "string",
"value": "string",
"confidence": 0,
"source": "explicit",
"created_at": "2026-01-15T12:00:00.000Z",
"updated_at": "2026-01-15T12:00:00.000Z",
"metadata": {}
}