Skip to content
OpenSouk

Merchant routes

Register a catalogue, then take referral-mode payment

List merchants

GET/v1/merchant

List registered merchants.

Query Parameters

page
integer·default 1

Below 1 becomes 1.

limit
integer·max 100·default 20

Below 1 OR above 100 becomes 20.

chain_id
integer

Absent, the server uses its first configured chain — Base Sepolia in the shipped default.

Example84532

Responses

Get a merchant

GET/v1/merchant/{id}

Get one merchant and the ids of its active products.

Path Parameters

idRequired
integer·min 1

Must be positive — 0 and below are a 400.

Example42

Query Parameters

chain_id
integer

Absent, the server uses its first configured chain — Base Sepolia in the shipped default.

Example84532

Responses

Get a product

GET/v1/merchant/product

Get one product by merchant and product id.

Query Parameters

merchant_idRequired
integer·min 1

Must be positive.

Example42
product_idRequired
string

32-byte hex, with or without 0x.

Example0x1f9a…
chain_id
integer

Absent, the server uses its first configured chain — Base Sepolia in the shipped default.

Example84532

Responses

Get a merchant's catalog

GET/v1/merchant/{id}/catalog

A merchant's active products, each with the endpoint buyers pay, its commission, sales, reviews and rank. At most 500 products.

Path Parameters

idRequired
integer
Example42

Query Parameters

chain_id
integer

Absent, the server uses its first configured chain — Base Sepolia in the shipped default.

Example84532

Responses

List product categories

GET/v1/product-categories

Every category a product can be registered under, grouped by kind, with an example review for each kind. The same on every chain, and cacheable for an hour.

Responses

Register a merchant

POST/v1/merchant/register

Sync a merchant NFT you have already minted and activated.

Request Body

application/json
merchant_idRequired
integer

Negative is a 400. An omitted merchant_id binds to 0 and passes that guard — it fails on the on-chain read instead.

Responses

Set merchant profile

POST/v1/merchant/profile

Partial update of the merchant's profile: description, landing page URL and default commission. Send only the fields to change; an omitted field keeps its stored value, and an empty string clears a text field. At least one field is required. The response is the stored profile.

Request Body

application/json
merchant_idRequired
integer

Must be positive.

description
string·max 2000

Optional. An empty string clears it.

landing_page_url
string·max 2048

Optional. http or https only, and must include a host. An empty string clears it.

default_commission_bps
integer·min 0·max 10000

Optional. Default commission for new products, in basis points (the contract's commissionBps bound). Off-chain only.

Responses

Set settlement visibility

POST/v1/merchant/settlement-visibility

Choose which facilitator wallet submits this merchant's x402 settlements. public settles from the wallet registered with x402scan, so your sales are indexed there; private settles from an unregistered wallet. Private is unlisted, not confidential: the transaction is still public on Base. New merchants start public. Applies to settlements started after the call returns.

Request Body

application/json
merchant_idRequired
integer

Zero or greater.

settlement_visibilityRequired
string
Values
publicprivate

Responses

Register a product

POST/v1/merchant/product

Attach metadata to a product you have already added on-chain.

Request Body

application/json
merchant_idRequired
integer

Negative is a 400.

product_idRequired
string

32-byte hex.

endpoint_urlRequired
string

http or https, with a host.

name
string
description
string
category
string

A selectable slug from GET /v1/product-categories, such as chain.rpc. The product's stored value re-sent unchanged is also accepted. What a review schema and a checklist key off.

Responses

Probe endpoint readiness

POST/v1/merchant/product/readiness

Check whether one of your endpoints is wired for referral payments.

Request Body

application/json
resourceRequired
string

http or https, with a host.

Responses

Get merchant stats

GET/v1/merchant/{id}/stats

Get a merchant's conversions, revenue and product counts.

Path Parameters

idRequired
integer·min 0

Zero is valid here; negative is a 400.

Example42

Query Parameters

chain_id
integer

Absent, the server uses its first configured chain — Base Sepolia in the shipped default.

Example84532

Responses

Reply to a review of your product

POST/v1/merchant/review-response

A merchant's public reply to one review of one of its own products. The reply is stored against the review and replaces any previous one, so a second call is an edit rather than a second reply.

Request Body

application/json
merchant_idRequired
integer

The merchant's ERC-8004 id. Id 0 is a real merchant.

review_idRequired
integer

The review being replied to. Must belong to this merchant.

bodyRequired
string·max 2000

Measured in characters, not bytes. No NUL byte.

Responses

Appeal a review as defamatory or false-factual

POST/v1/merchant/review-appeal

Report one review of your own product for an admin to adjudicate. One appeal per review, ever — a second submission returns the existing appeal rather than opening another.

Request Body

application/json
merchant_idRequired
integer
review_idRequired
integer
reasonRequired
string·max 4000

Measured in characters, not bytes. No NUL byte.

Responses

Read one appeal's status

GET/v1/merchant/review-appeal/{id}

Poll an appeal you submitted. An upheld appeal hides its review, so this read is deliberately not filtered by review visibility — otherwise the confirmation you are polling for would disappear at the moment it arrives. The admin's own note and identity are never returned.

Path Parameters

idRequired
integer

The appeal_id returned when the appeal was submitted.

Responses

Verify a payment

POST/verify

Check a payment payload without moving money.

Request Body

application/json
x402VersionRequired
integer

Must be 2. Anything else is a 400.

Values
2
paymentPayloadRequired
object

Carries payload.signature, payload.authorization, accepted, and extensions. buyerAgentId is a DECIMAL STRING; absent, null or "" all mean an agent-less buyer, and a present-but-malformed value is rejected.

paymentRequirementsRequired
object

extra.name and extra.version are the USDC contract's own EIP-712 domain and are required — without them the payload cannot be recovered.

Responses

Settle a payment

POST/settle

Submit a payment on-chain and wait for the receipt.

Request Body

application/json
x402VersionRequired
integer

Must be 2. Anything else is a 400.

Values
2
paymentPayloadRequired
object

Carries payload.signature, payload.authorization, accepted, and extensions. buyerAgentId is a DECIMAL STRING; absent, null or "" all mean an agent-less buyer, and a present-but-malformed value is rejected.

paymentRequirementsRequired
object

extra.name and extra.version are the USDC contract's own EIP-712 domain and are required — without them the payload cannot be recovered.

Responses

Supported payment kinds

GET/supported

List the payment kinds this facilitator accepts.

Responses

Attribution public key

GET/attribution/public-key

Get the public key an attribution token verifies against.

Responses

Attest an MPP charge

POST/mpp/charge

Attest a completed one-off charge so it can be split on-chain.

Request Body

application/json
txHashRequired
string

The charge transfer's 32-byte hash, 0x-prefixed or bare. Also the paymentRef.

attributionTokenRequired
string

The base64url token, unpadded.

buyerAgentIdRequired
integer

Required, and 0 is valid. Absent is a 400 — the field is nullable precisely so an omitted id cannot be read as agent 0.

buyerSignatureRequired
string

65 bytes over the ChargeCommitment.

Responses

Next steps