Developers
CargoFlow API reference
Public reads need no credentials. Parties write by signing a fixed message with their own wallet; evidence gateways sign every request with their device key. The backend never holds a party key.
Base URL
https://cargoflow-api-75ul.onrender.com- Auth
- None for reads · EIP-191 or device signature for writes
- Errors
{"error":{"code","message"}}
Signing recipes
The two ways to write. Reads need neither.
Wallet-signed requests
EIP-191 personal_sign over the exact text in each operation's x-cargoflow-signed-message. Contract wallets (passkey smart accounts) are checked through EIP-1271.
TypeScript (viem)
// 1. Take the operation's x-cargoflow-signed-message template, e.g. for POST /v1/notifications/read:
// "CargoFlow notifications read\naddress: <address>\nids: <id,id | all>\nissued: <t>"
const issuedAt = Math.floor(Date.now() / 1000); // within 10 minutes of the server clock
const message = [
"CargoFlow notifications read",
`address: ${address.toLowerCase()}`, // ids and addresses lower case
"ids: all",
`issued: ${issuedAt}`,
].join("\n"); // "\n" between lines, no trailing newline
// 2. EIP-191 personal_sign with the party's wallet (EOA or EIP-1271 contract wallet)
const signature = await wallet.signMessage({ account: address, message });
// 3. Send the fields plus issuedAt and signature. Each signature works once (409 "replayed" after).
await fetch("https://cargoflow-api-75ul.onrender.com/v1/notifications/read", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ address, issuedAt, signature }),
});Gateway-signed telemetry
A gateway registered by the exporter (Ed25519, P-256 secure element or a WebAuthn passkey) signs each request. @cargoflow/gateway does this for you.
Signing string and headers
# Signing string (bytes the device signs), lines joined by "\n":
CARGOFLOW-V1
POST
/v1/shipments/<id>/telemetry
<unix seconds>
<hex sha256(exact request body)>
# Headers
X-Source-Id: src-… # returned when the exporter registered the gateway
X-Timestamp: <unix seconds> # within 5 minutes
X-Signature: base64url(signature)
# ed25519 Ed25519 over the signing string
# p256 ECDSA P-256 over sha256(signing string), DER or raw r||s
# webauthn passkey assertion with challenge = sha256(signing string), plus
# X-WebAuthn-Authenticator-Data and X-WebAuthn-Client-Data (base64url)Endpoints
Every operation has a Test Request button that calls the live API.
Loading the API reference…