Shop
3 operations under /v1/shop/agent (GET POST): parameters, status codes, refusal bodies, and the same request in curl, HTTP, Python and TypeScript.
Base URL: https://api.codespar.dev
Every operation below requires a Bearer token. See Authentication.
GET /v1/shop/agent/instruments
https://api.codespar.dev/v1/shop/agent/instrumentsA person's cards, masked
Scope shop:instruments:read. Brand and last four of the person's active cards, as references an assistant can name; choosing one stays the person's act at Pagar.
What an assistant can and cannot do. It proposes a purchase and reads where it stands; it never pays, approves, saves a card or logs in at a store. A verified person presses Pagar on the dashboard and completes what the purchase waits for (the protected card or CVV form, the store login); the purchase then runs through the same executor as the Shop's own chat, at most once at the store. No answer carries a card number, a security code, a cookie or a collect secret. Test projects only in this first delivery; behind SHOP_PURCHASES_ENABLED.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner | string | yes | The person whose masked cards the assistant may reference. |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
400 | object | owner is missing or malformed. |
403 | object | The key does not hold shop:instruments:read. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
instruments | array of object | yes | — |
curl -X GET https://api.codespar.dev/v1/shop/agent/instruments \
-H "Authorization: Bearer $CODESPAR_API_KEY"GET /v1/shop/agent/instruments HTTP/1.1
Host: api.codespar.dev
Authorization: Bearer $CODESPAR_API_KEYimport os
import requests
res = requests.get(
"https://api.codespar.dev/v1/shop/agent/instruments",
headers={"Authorization": f"Bearer {os.environ['CODESPAR_API_KEY']}"},
)
res.raise_for_status()
data = res.json()const res = await fetch("https://api.codespar.dev/v1/shop/agent/instruments", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.CODESPAR_API_KEY}`,
},
});
const data = await res.json();const r = await cs.api.response("get", "/v1/shop/agent/instruments", {
query: {
owner: "string"
}
});
// r.status is one of the documented statuses (200, 403),
// each with its own body shape in r.data; nothing here throws on 403.
if (r.ok) {
console.log(r.data);
}{
"instruments": [
{
"id": "obj_0000000000000000",
"kind": "byo_card",
"brand": "string",
"last4": "string",
"status": "active"
}
]
}POST /v1/shop/agent/purchases
https://api.codespar.dev/v1/shop/agent/purchasesPropose a purchase at a supported store (never an order)
Scope shop:purchases:write. The store, its origin and its prices come from the server's registry and the store's own catalog, never from the request. The same agent_id and idempotency_key with the same intent answers the same purchase (idempotent_replay: true).
What an assistant can and cannot do. It proposes a purchase and reads where it stands; it never pays, approves, saves a card or logs in at a store. A verified person presses Pagar on the dashboard and completes what the purchase waits for (the protected card or CVV form, the store login); the purchase then runs through the same executor as the Shop's own chat, at most once at the store. No answer carries a card number, a security code, a cookie or a collect secret. Test projects only in this first delivery; behind SHOP_PURCHASES_ENABLED.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
agent_id | string | yes | — |
idempotency_key | string | yes | — |
items | array of object | yes | — |
merchant | string | yes | — |
payment_method | "card" | "store_on_file" | no | — |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
201 | object | OK |
400 | object | The body did not match the schema. |
403 | object | The key does not hold shop:purchases:write. |
409 | object | No mandate permits the store, or the project is not Test. |
422 | object | The agent, the store, the rail or an item is not one that can be bought. |
503 | object | Shop purchases are off on this deployment. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
idempotent_replay | boolean | yes | — |
proposal | object,null | yes | The proposal card as the dashboard shows it. |
purchase | object | yes | — |
curl -X POST https://api.codespar.dev/v1/shop/agent/purchases \
-H "Authorization: Bearer $CODESPAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "agt_0000000000000000",
"merchant": "string",
"items": [
{
"sku_id": "sku_0000000000000000",
"quantity": 0
}
],
"payment_method": "card",
"idempotency_key": "string"
}'POST /v1/shop/agent/purchases HTTP/1.1
Host: api.codespar.dev
Authorization: Bearer $CODESPAR_API_KEY
Content-Type: application/json
{
"agent_id": "agt_0000000000000000",
"merchant": "string",
"items": [
{
"sku_id": "sku_0000000000000000",
"quantity": 0
}
],
"payment_method": "card",
"idempotency_key": "string"
}import os
import requests
res = requests.post(
"https://api.codespar.dev/v1/shop/agent/purchases",
headers={"Authorization": f"Bearer {os.environ['CODESPAR_API_KEY']}"},
json={
"agent_id": "agt_0000000000000000",
"merchant": "string",
"items": [
{
"sku_id": "sku_0000000000000000",
"quantity": 0
}
],
"payment_method": "card",
"idempotency_key": "string"
},
)
res.raise_for_status()
data = res.json()const res = await fetch("https://api.codespar.dev/v1/shop/agent/purchases", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CODESPAR_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"agent_id": "agt_0000000000000000",
"merchant": "string",
"items": [
{
"sku_id": "sku_0000000000000000",
"quantity": 0
}
],
"payment_method": "card",
"idempotency_key": "string"
}),
});
const data = await res.json();const r = await cs.api.response("post", "/v1/shop/agent/purchases", {
body: {
agent_id: "agt_0000000000000000",
merchant: "string",
items: [
{
sku_id: "sku_0000000000000000",
quantity: 0
}
],
payment_method: "card",
idempotency_key: "string"
}
});
// r.status is one of the documented statuses (200, 403, 422),
// each with its own body shape in r.data; nothing here throws on 403.
if (r.ok) {
console.log(r.data);
}{
"purchase": {
"id": "obj_0000000000000000",
"kind": "purchase",
"state": "drafted",
"run_state": "ready",
"awaiting": {
"reason": "instrument"
},
"merchant": {
"id": "obj_0000000000000000",
"name": "Example"
},
"items": [
{
"sku_id": "sku_0000000000000000",
"name": "Example",
"quantity": 0,
"unit_price_minor": 1
}
],
"total_minor": 1,
"currency": "BRL",
"payment_method": "card",
"order": {
"id": "obj_0000000000000000",
"status": "string",
"amount_minor": 1000
},
"receipt": {
"funding_origin": "external_card",
"wallet_debit": false
},
"failure": {
"code": "string"
},
"next_action": "string"
},
"proposal": {},
"idempotent_replay": true
}GET /v1/shop/agent/purchases/{id}
https://api.codespar.dev/v1/shop/agent/purchases/{id}Where a purchase stands
Scope shop:purchases:read. References and states only: the order the store answered, a receipt marked as external (no Wallet debit), what it waits for.
What an assistant can and cannot do. It proposes a purchase and reads where it stands; it never pays, approves, saves a card or logs in at a store. A verified person presses Pagar on the dashboard and completes what the purchase waits for (the protected card or CVV form, the store login); the purchase then runs through the same executor as the Shop's own chat, at most once at the store. No answer carries a card number, a security code, a cookie or a collect secret. Test projects only in this first delivery; behind SHOP_PURCHASES_ENABLED.
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
403 | object | The key does not hold shop:purchases:read. |
404 | object | Not Found |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
purchase | object | yes | — |
curl -X GET https://api.codespar.dev/v1/shop/agent/purchases/{id} \
-H "Authorization: Bearer $CODESPAR_API_KEY"GET /v1/shop/agent/purchases/{id} HTTP/1.1
Host: api.codespar.dev
Authorization: Bearer $CODESPAR_API_KEYimport os
import requests
res = requests.get(
"https://api.codespar.dev/v1/shop/agent/purchases/{id}",
headers={"Authorization": f"Bearer {os.environ['CODESPAR_API_KEY']}"},
)
res.raise_for_status()
data = res.json()const res = await fetch("https://api.codespar.dev/v1/shop/agent/purchases/{id}", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.CODESPAR_API_KEY}`,
},
});
const data = await res.json();const r = await cs.api.response("get", "/v1/shop/agent/purchases/{id}");
// r.status is one of the documented statuses (200, 403),
// each with its own body shape in r.data; nothing here throws on 403.
if (r.ok) {
console.log(r.data);
}{
"purchase": {
"id": "obj_0000000000000000",
"kind": "purchase",
"state": "drafted",
"run_state": "ready",
"awaiting": {
"reason": "instrument"
},
"merchant": {
"id": "obj_0000000000000000",
"name": "Example"
},
"items": [
{
"sku_id": "sku_0000000000000000",
"name": "Example",
"quantity": 0,
"unit_price_minor": 1
}
],
"total_minor": 1,
"currency": "BRL",
"payment_method": "card",
"order": {
"id": "obj_0000000000000000",
"status": "string",
"amount_minor": 1000
},
"receipt": {
"funding_origin": "external_card",
"wallet_debit": false
},
"failure": {
"code": "string"
},
"next_action": "string"
}
}