Pay per action in USDC. No account and no API key: a wallet signature authorizes each request and settlement happens on-chain through the Coinbase CDP facilitator.
One round-trip to learn the price, one to pay and execute. The 402 response is the price quote; the retry carries the signed payment.
POST /api/x402/register with no payment header returns 402 with payment requirements plus a SIWE nonce in extensions. Sign the SIWE message and the payment, then retry. Details under Wallet registration.
Send the request as if the API were free. Pick a network with ?network= (default: base).
The JSON body and the PAYMENT-REQUIRED response header carry the same object. accepts lists exactly one way to pay: scheme exact on your chosen network, amount in atomic USDC units (6 decimals), recipient in payTo.
EVM networks: sign an EIP-3009 authorization under the USDC EIP-712 domain carried in extra (name USD Coin, version 2). Solana: extra carries the facilitator-provided feePayer, and the exact scheme builds a partially signed transaction with it. Client libraries such as @x402/evm and @x402/svm build this payload from the accepts entry.
Base64-encode the signed payment payload JSON and send it in the PAYMENT-SIGNATURE header on the same request. The v1 header name X-PAYMENT is also accepted.
Verification runs off-chain at the Coinbase CDP facilitator and includes sanctions screening. A pending charge is recorded before on-chain settlement, then the action runs. If a refundable step fails after settlement, the charge is refunded on-chain and the error body carries refundInitiated and refundTxHash. Settlement details return base64-encoded in the PAYMENT-RESPONSE header (v1 alias X-PAYMENT-RESPONSE).
connect returns oauthUrl and connectionToken. Open the URL in a browser, then poll GET /api/x402/oauth/status with the token until status is connected.
{
"x402Version": 2,
"resource": { "url": "https://sharetopus.com/api/x402/post-now" },
"accepts": [
{
"scheme": "exact",
"network": "eip155:8453",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"amount": "750000",
"payTo": "0xSHARETOPUS_RECEIVING_ADDRESS",
"maxTimeoutSeconds": 300,
"extra": { "name": "USD Coin", "version": "2" }
}
],
"error": "PAYMENT-SIGNATURE header is required"
}# 1. No payment attached: the server answers 402
curl -X POST "https://sharetopus.com/api/x402/post-now" \
-H "Content-Type: application/json" \
-d '{ "social_account_id": "...", "platform": "tiktok", "post_type": "text", "description": "hello" }'
# 2. Retry the same request with the signed payment payload
curl -X POST "https://sharetopus.com/api/x402/post-now" \
-H "Content-Type: application/json" \
-H "PAYMENT-SIGNATURE: <signed-payment-payload>" \
-d '{ "social_account_id": "...", "platform": "tiktok", "post_type": "text", "description": "hello" }'{
"success": true,
"data": { "...": "endpoint-specific result, see each endpoint" },
"chargeId": "8f0a3c52-7c1e-4b8e-9f21-d4a0c0b6e7aa",
"network": "base",
"txHash": "0x6f2e8a1b...",
"payerAddress": "0x9af31c5e..."
}HTTP/2 200
PAYMENT-RESPONSE: <base64>
X-PAYMENT-RESPONSE: <base64>
# decoded PAYMENT-RESPONSE
{
"success": true,
"payer": "0x9af31c5e...",
"transaction": "0x6f2e8a1b...",
"network": "eip155:8453",
"amount": "750000"
}One-time onboarding, itself paid (the register action). The same POST route serves the challenge (no payment header) and the verify (payment header present).
Call with no PAYMENT-SIGNATURE header. Returns 402 with the payment requirements for the register action plus a fresh SIWE nonce in extensions. The nonce is single use and expires 300 seconds after issuance.
| Parameter | Type | Required | Description |
|---|---|---|---|
| network | string | Optional | Payment network: base, polygon, arbitrum, or solana. Default base. Unknown values return 400 unsupported_network. |
curl -X POST "https://sharetopus.com/api/x402/register?network=base"{
"x402Version": 2,
"resource": { "url": "https://sharetopus.com/api/x402/register" },
"accepts": [
{
"scheme": "exact",
"network": "eip155:8453",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"amount": "1000000",
"payTo": "0xSHARETOPUS_RECEIVING_ADDRESS",
"maxTimeoutSeconds": 300,
"extra": { "name": "USD Coin", "version": "2" }
}
],
"extensions": {
"siweNonce": "kPaXM3GZbXVtMW3sJq2r9",
"siweExpiresAt": "2026-06-09T12:05:00.000Z"
}
}Retry the same route with the signed payment in PAYMENT-SIGNATURE and the signed sign-in message in the body. EVM wallets sign an EIP-4361 (SIWE) message; smart wallets verify via EIP-1271/ERC-6492 through the network RPC. Solana wallets sign the SIWS message text with Ed25519. The verify path follows the network family of ?network. A wallet flagged by sanctions screening is rejected with 403 sanctioned.
| Parameter | Type | Required | Description |
|---|---|---|---|
| siweMessage | string | Required | The signed message text. Must carry the nonce from the challenge, the domain sharetopus.com, and a URI exactly equal to https://sharetopus.com/api/x402/register. EVM messages must also carry the chain id of the payment network. |
| siweSignature | string | Required | EVM: hex signature, 0x-prefixed. Solana: base58 Ed25519 signature. |
| Parameter | Type | Required | Description |
|---|---|---|---|
| principalId | string | Required | Wallet principal id, format wallet_<32 hex chars>. |
| walletId | string | Required | Same value as principalId. |
| address | string | Required | Registered wallet address. EVM addresses are stored lowercase; Solana addresses keep their casing. |
| chain | string | Required | base, polygon, arbitrum, or solana. |
| sanctionsStatus | string | Required | clean for fresh registrations. |
| isNew | boolean | Required | false when the wallet was already registered. |
| chargeId | string | null | Required | Charge id for this registration. Null when isNew is false. |
curl -X POST "https://sharetopus.com/api/x402/register?network=base" \
-H "Content-Type: application/json" \
-H "PAYMENT-SIGNATURE: <signed-payment-payload>" \
-d '{
"siweMessage": "<EIP-4361 message: domain sharetopus.com, uri https://sharetopus.com/api/x402/register, chain id of your network, nonce from the challenge>",
"siweSignature": "0x57c2b1..."
}'{
"principalId": "wallet_2f6a1c0e9b8d4a7f5c3e1d2b4a6c8e0f",
"walletId": "wallet_2f6a1c0e9b8d4a7f5c3e1d2b4a6c8e0f",
"address": "0x9af31c5e...",
"chain": "base",
"sanctionsStatus": "clean",
"isNew": true,
"chargeId": "8f0a3c52-7c1e-4b8e-9f21-d4a0c0b6e7aa"
}Paid OAuth initiation for linkedin, tiktok, pinterest, and instagram. No request body: the wallet is identified by the payment signature alone.
Call with ?platform and no PAYMENT-SIGNATURE header. Returns 402 quoting the connect_account price. No SIWE nonce here; the wallet is already registered.
| Parameter | Type | Required | Description |
|---|---|---|---|
| platform | string | Required | One of linkedin, tiktok, pinterest, instagram. Anything else returns 400 invalid_platform. |
| network | string | Optional | base, polygon, arbitrum, or solana. Default base. |
curl -X POST "https://sharetopus.com/api/x402/connect?platform=tiktok"{
"x402Version": 2,
"resource": { "url": "https://sharetopus.com/api/x402/connect" },
"accepts": [
{
"scheme": "exact",
"network": "eip155:8453",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"amount": "500000",
"payTo": "0xSHARETOPUS_RECEIVING_ADDRESS",
"maxTimeoutSeconds": 300,
"extra": { "name": "USD Coin", "version": "2" }
}
]
}Retry with the payment attached. On success the wallet is charged connect_account and the response carries the OAuth URL to open in a browser plus a connection token for status polling. The pending connection stays claimable for 15 minutes. An unregistered paying wallet gets 401 wallet_not_registered on this route.
| Parameter | Type | Required | Description |
|---|---|---|---|
| connectionId | string | Required | Id of the pending connection. |
| platform | string | Required | Echoes the requested platform. |
| oauthUrl | string | null | Required | Authorization URL to open in a browser. Null on idempotent reconnects. |
| connectionToken | string | null | Required | Opaque signed token for GET /api/x402/oauth/status, sent as Authorization: Bearer. Valid until the connection expiry plus a 1 hour grace period. Null on reconnects whose account predates connection tracking. |
| expiresAt | string | Required | ISO timestamp. New connections expire 15 minutes after creation. |
| isReconnect | boolean | Required | True when an existing healthy connection was returned instead of starting OAuth. |
curl -X POST "https://sharetopus.com/api/x402/connect?platform=tiktok" \
-H "PAYMENT-SIGNATURE: <signed-payment-payload>"{
"connectionId": "e3b7c9d1-2a4f-48e0-b1c2-9d8e7f6a5b4c",
"platform": "tiktok",
"oauthUrl": "https://www.tiktok.com/v2/auth/authorize/?...",
"connectionToken": "v1.eyJjb25uZWN0aW9uSWQiOiAi...In0.5rT9vQ...",
"expiresAt": "2026-06-09T12:15:00.000Z",
"isReconnect": false
}Free polling endpoint. The connection token is the only credential.
Send the connection token from connect or reauth as a Bearer token. Each poll increments a per-connection counter; at 720 polls the endpoint returns 429 poll_limit_exceeded for that connection. No poll interval is suggested by the API: polling is capped and rate limited at 120 requests per minute per IP, cadence is up to the client. A pending connection past its expiry is reported as expired. After the user finishes OAuth in the browser, status moves to connected.
| Parameter | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Required | Bearer <connectionToken>. |
| Parameter | Type | Required | Description |
|---|---|---|---|
| connectionId | string | Required | Connection being polled. |
| platform | string | Required | OAuth platform. |
| status | string | Required | pending, connected, expired, failed, or revoked. |
| connectedAt | string | null | Required | Set when status reaches connected. |
| expiresAt | string | Required | When the pending connection stops being claimable. |
| socialAccountId | string | null | Required | The connected account id, usable with post endpoints once set. |
| pollCount | number | Required | Poll count after this request, toward the 720 cap. |
| errorCode | string | null | Required | Set when the OAuth flow failed. |
| errorMessage | string | null | Required | Human-readable failure detail. |
curl "https://sharetopus.com/api/x402/oauth/status" \
-H "Authorization: Bearer v1.eyJjb25uZWN0aW9uSWQiOiAi...In0.5rT9vQ..."{
"connectionId": "e3b7c9d1-2a4f-48e0-b1c2-9d8e7f6a5b4c",
"platform": "tiktok",
"status": "connected",
"connectedAt": "2026-06-09T12:03:21.000Z",
"expiresAt": "2026-06-09T12:15:00.000Z",
"socialAccountId": "5b1f0c4e-3d2a-4f6b-8c9d-0e1f2a3b4c5d",
"pollCount": 14,
"errorCode": null,
"errorMessage": null
}{
"error": "poll_limit_exceeded",
"message": "Poll limit reached for this connection (720)."
}Re-authenticate an expired social connection. Paid, same connect_account action as connect.
For a connected account whose platform token expired (is_available false in the connections list). Returns a fresh OAuth URL and connection token. The target account must belong to the paying wallet. Ownership and eligibility checks run after settlement: a failed check (account not found, not owned, reauth not needed, unsupported platform) returns 500 with the charge refunded on-chain and refundInitiated true in the body.
| Parameter | Type | Required | Description |
|---|---|---|---|
| social_account_id | string (uuid) | Required | Account id from GET /api/x402/connections. |
| Parameter | Type | Required | Description |
|---|---|---|---|
| connectionId | string | Required | New pending connection id. |
| platform | string | Required | Platform of the account. |
| oauthUrl | string | Required | Authorization URL to open in a browser. |
| connectionToken | string | Required | Bearer token for status polling. |
| expiresAt | string | Required | 15 minutes after creation. |
curl -X POST "https://sharetopus.com/api/x402/reauth" \
-H "Content-Type: application/json" \
-H "PAYMENT-SIGNATURE: <signed-payment-payload>" \
-d '{ "social_account_id": "5b1f0c4e-3d2a-4f6b-8c9d-0e1f2a3b4c5d" }'{
"success": true,
"data": {
"connectionId": "a91c4e7f-6b2d-4c8a-9e0f-1d2c3b4a5e6f",
"platform": "linkedin",
"oauthUrl": "https://www.linkedin.com/oauth/v2/authorization?...",
"connectionToken": "v1.eyJjb25uZWN0aW9uSWQiOiAi...In0.8wY2xK...",
"expiresAt": "2026-06-09T12:15:00.000Z"
},
"chargeId": "8f0a3c52-7c1e-4b8e-9f21-d4a0c0b6e7aa",
"network": "base",
"txHash": "0x6f2e8a1b...",
"payerAddress": "0x9af31c5e..."
}Publish immediately to one connected account. The price follows the post type.
Charges post.text, post.image, or post.video based on post_type. Posting runs asynchronously after settlement; the response identifies the dispatched work, not the platform post id. If the dispatch fails, the charge is refunded on-chain.
| Parameter | Type | Required | Description |
|---|---|---|---|
| social_account_id | string (uuid) | Required | Connected account to post from. |
| platform | string | Required | linkedin, tiktok, pinterest, or instagram. Must match the account. |
| post_type | string | Required | text, image, or video. Selects the pricing action. |
| description | string | null | Required | Post body text. The key is required; the value may be null. |
| media_storage_path | string | Optional | Required for image and video posts. The path returned by POST /api/x402/upload-url. |
| title | string | null | Optional | Post title where the platform supports one. |
| cover_timestamp | number | Optional | Video cover frame timestamp. |
| pinterest_board_id | string | Optional | Pinterest board id. |
| pinterest_board_name | string | Optional | Pinterest board name. |
| pinterest_link | string | Optional | Outbound link for Pinterest pins. |
| idempotency_key | string | Optional | Client-supplied key to dedupe retries. |
| Parameter | Type | Required | Description |
|---|---|---|---|
| batchId | string | Required | Batch identifier for this dispatch. |
| eventIds | string[] | Required | Ids of the dispatched posting jobs. |
| dispatched | number | Required | Count of jobs dispatched. |
curl -X POST "https://sharetopus.com/api/x402/post-now" \
-H "Content-Type: application/json" \
-H "PAYMENT-SIGNATURE: <signed-payment-payload>" \
-d '{
"social_account_id": "5b1f0c4e-3d2a-4f6b-8c9d-0e1f2a3b4c5d",
"platform": "tiktok",
"post_type": "video",
"description": "Launch day.",
"media_storage_path": "wallet_2f6a1c0e.../launch.mp4"
}'{
"success": true,
"data": {
"batchId": "f7e6d5c4-b3a2-4190-8f7e-6d5c4b3a2918",
"eventIds": ["a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"],
"dispatched": 1
},
"chargeId": "8f0a3c52-7c1e-4b8e-9f21-d4a0c0b6e7aa",
"network": "base",
"txHash": "0x6f2e8a1b...",
"payerAddress": "0x9af31c5e..."
}Same body as post-now plus a future timestamp.
Charges the same post.text / post.image / post.video actions. The post is stored and published by the scheduler at scheduled_at. The body accepts every post-now field plus the two below. Scheduling failures after settlement are refunded on-chain.
| Parameter | Type | Required | Description |
|---|---|---|---|
| scheduled_at | string | Required | ISO 8601 datetime. Must parse and be in the future. |
| post_options | object | null | Optional | Per-platform options object passed through to the scheduler. |
| Parameter | Type | Required | Description |
|---|---|---|---|
| batchId | string | Required | Batch identifier for this schedule call. |
| scheduleIds | string[] | Required | Ids of the created scheduled posts. Use them with reschedule, cancel, and delete. |
| inserted | number | Required | Count of posts stored. |
curl -X POST "https://sharetopus.com/api/x402/schedule" \
-H "Content-Type: application/json" \
-H "PAYMENT-SIGNATURE: <signed-payment-payload>" \
-d '{
"social_account_id": "5b1f0c4e-3d2a-4f6b-8c9d-0e1f2a3b4c5d",
"platform": "pinterest",
"post_type": "image",
"description": "Summer lookbook, part 2.",
"media_storage_path": "wallet_2f6a1c0e.../lookbook-2.jpg",
"title": "Summer lookbook",
"pinterest_board_id": "1234567890",
"pinterest_link": "https://example.com/lookbook",
"scheduled_at": "2026-06-12T16:00:00.000Z"
}'{
"success": true,
"data": {
"batchId": "f7e6d5c4-b3a2-4190-8f7e-6d5c4b3a2918",
"scheduleIds": ["c9d8e7f6-a5b4-4c3d-2e1f-0a9b8c7d6e5f"],
"inserted": 1
},
"chargeId": "8f0a3c52-7c1e-4b8e-9f21-d4a0c0b6e7aa",
"network": "base",
"txHash": "0x6f2e8a1b...",
"payerAddress": "0x9af31c5e..."
}Mint a signed upload URL for post media.
Charges upload_url. Returns a signed storage URL. Upload the file to uploadUrl, then pass path as media_storage_path when posting or scheduling. Wallet storage is capped at 5 GB in total; a request that would exceed the cap fails after settlement with quota_exceeded and the charge is refunded.
| Parameter | Type | Required | Description |
|---|---|---|---|
| filename | string | Required | 1 to 255 characters. |
| content_type | string | Required | MIME type of the file. |
| size_bytes | number | Required | Positive integer. Max 262144000 (250 MB) per file. |
| Parameter | Type | Required | Description |
|---|---|---|---|
| uploadUrl | string | Required | Signed upload URL. |
| path | string | Required | Storage path to use as media_storage_path in post-now and schedule. |
curl -X POST "https://sharetopus.com/api/x402/upload-url" \
-H "Content-Type: application/json" \
-H "PAYMENT-SIGNATURE: <signed-payment-payload>" \
-d '{ "filename": "launch.mp4", "content_type": "video/mp4", "size_bytes": 10485760 }'{
"success": true,
"data": {
"uploadUrl": "https://...supabase.co/storage/v1/object/upload/sign/...",
"path": "wallet_2f6a1c0e.../launch.mp4"
},
"chargeId": "8f0a3c52-7c1e-4b8e-9f21-d4a0c0b6e7aa",
"network": "base",
"txHash": "0x6f2e8a1b...",
"payerAddress": "0x9af31c5e..."
}Move, cancel, or hard-delete scheduled posts. The batch endpoints accept 1 to 50 ids per call.
Charges reschedule. Moves one scheduled post to a new future time.
| Parameter | Type | Required | Description |
|---|---|---|---|
| post_id | string (uuid) | Required | Scheduled post to move. |
| new_scheduled_time | string | Required | ISO 8601 datetime. Must be in the future. |
| Parameter | Type | Required | Description |
|---|---|---|---|
| succeeded | number | Required | Posts moved. |
| resumed | number | Required | Previously paused posts resumed by the move. |
curl -X POST "https://sharetopus.com/api/x402/reschedule" \
-H "Content-Type: application/json" \
-H "PAYMENT-SIGNATURE: <signed-payment-payload>" \
-d '{
"post_id": "c9d8e7f6-a5b4-4c3d-2e1f-0a9b8c7d6e5f",
"new_scheduled_time": "2026-06-13T09:00:00.000Z"
}'{
"success": true,
"data": { "succeeded": 1, "resumed": 0 },
"chargeId": "8f0a3c52-7c1e-4b8e-9f21-d4a0c0b6e7aa",
"network": "base",
"txHash": "0x6f2e8a1b...",
"payerAddress": "0x9af31c5e..."
}Charges cancel. Cancels 1 to 50 scheduled posts owned by the wallet. Cancelled posts keep their row and media.
| Parameter | Type | Required | Description |
|---|---|---|---|
| post_ids | string[] (uuid) | Required | 1 to 50 scheduled post ids. |
| Parameter | Type | Required | Description |
|---|---|---|---|
| succeeded | number | Required | Posts cancelled. |
| failed | number | Required | Posts that could not be cancelled. |
curl -X POST "https://sharetopus.com/api/x402/cancel" \
-H "Content-Type: application/json" \
-H "PAYMENT-SIGNATURE: <signed-payment-payload>" \
-d '{ "post_ids": ["c9d8e7f6-a5b4-4c3d-2e1f-0a9b8c7d6e5f"] }'{
"success": true,
"data": { "succeeded": 1, "failed": 0 },
"chargeId": "8f0a3c52-7c1e-4b8e-9f21-d4a0c0b6e7aa",
"network": "base",
"txHash": "0x6f2e8a1b...",
"payerAddress": "0x9af31c5e..."
}Charges delete. Hard deletes 1 to 50 scheduled or completed posts and their stored media. Not reversible.
| Parameter | Type | Required | Description |
|---|---|---|---|
| post_ids | string[] (uuid) | Required | 1 to 50 post ids. |
| Parameter | Type | Required | Description |
|---|---|---|---|
| succeeded | number | Required | Posts deleted. |
| failed | number | Required | Posts that could not be deleted. |
| mediaDeleted | number | Required | Media files removed from storage. |
curl -X POST "https://sharetopus.com/api/x402/delete" \
-H "Content-Type: application/json" \
-H "PAYMENT-SIGNATURE: <signed-payment-payload>" \
-d '{ "post_ids": ["c9d8e7f6-a5b4-4c3d-2e1f-0a9b8c7d6e5f"] }'{
"success": true,
"data": { "succeeded": 1, "failed": 0, "mediaDeleted": 1 },
"chargeId": "8f0a3c52-7c1e-4b8e-9f21-d4a0c0b6e7aa",
"network": "base",
"txHash": "0x6f2e8a1b...",
"payerAddress": "0x9af31c5e..."
}Paid GET endpoints. The payment signature authenticates the wallet; the 402 flow is the same as for POST routes.
Charges list_connections. Returns the wallet's connected social accounts. Platform tokens are never included.
| Parameter | Type | Required | Description |
|---|---|---|---|
| include_unavailable | string | Optional | true to include accounts whose platform token expired (candidates for reauth). Default: only available accounts. |
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string | Required | Account id, used as social_account_id elsewhere. |
| platform | string | Required | Social platform of the account. |
| display_name | string | null | Required | Profile display name. |
| username | string | null | Required | Profile handle. |
| avatar_url | string | null | Required | Profile image URL. |
| is_available | boolean | Required | False when the platform token expired; use reauth. |
| follower_count | number | null | Required | Follower count at last sync. |
curl "https://sharetopus.com/api/x402/connections?include_unavailable=true" \
-H "PAYMENT-SIGNATURE: <signed-payment-payload>"{
"success": true,
"data": {
"accounts": [
{
"id": "5b1f0c4e-3d2a-4f6b-8c9d-0e1f2a3b4c5d",
"platform": "tiktok",
"display_name": "Studio",
"username": "studio.daily",
"avatar_url": "https://...",
"is_available": true,
"follower_count": 1280
}
]
},
"chargeId": "8f0a3c52-7c1e-4b8e-9f21-d4a0c0b6e7aa",
"network": "base",
"txHash": "0x6f2e8a1b...",
"payerAddress": "0x9af31c5e..."
}Charges list_posts. Returns the wallet's scheduled posts.
| Parameter | Type | Required | Description |
|---|---|---|---|
| status | string | Optional | scheduled, queued, processing, posted, failed, or cancelled. |
| platform | string | Optional | Filter by platform. |
| limit | number | Optional | 1 to 100. Default 20. |
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string | Required | Scheduled post id. |
| scheduled_at | string | Required | Publish time, ISO 8601. |
| status | string | Required | scheduled, queued, processing, posted, failed, or cancelled. |
| platform | string | Required | Target platform. |
| post_title | string | null | Required | Title, when set. |
| post_description | string | null | Required | Body text, when set. |
| media_type | string | Required | text, image, or video. |
| media_storage_path | string | Required | Storage path of the attached media. |
| error_message | string | null | Required | Set when publishing failed. |
| batch_id | string | null | Required | Batch the post was created in. |
| created_via | string | Required | x402 for posts created through this API. |
curl "https://sharetopus.com/api/x402/scheduled-posts?status=scheduled&limit=20" \
-H "PAYMENT-SIGNATURE: <signed-payment-payload>"{
"success": true,
"data": {
"posts": [
{
"id": "c9d8e7f6-a5b4-4c3d-2e1f-0a9b8c7d6e5f",
"scheduled_at": "2026-06-12T16:00:00.000Z",
"status": "scheduled",
"platform": "pinterest",
"post_title": "Summer lookbook",
"post_description": "Summer lookbook, part 2.",
"media_type": "image",
"media_storage_path": "wallet_2f6a1c0e.../lookbook-2.jpg",
"error_message": null,
"batch_id": "f7e6d5c4-b3a2-4190-8f7e-6d5c4b3a2918",
"created_via": "x402"
}
]
},
"chargeId": "8f0a3c52-7c1e-4b8e-9f21-d4a0c0b6e7aa",
"network": "base",
"txHash": "0x6f2e8a1b...",
"payerAddress": "0x9af31c5e..."
}Charges list_history. Returns published content records for the wallet.
| Parameter | Type | Required | Description |
|---|---|---|---|
| platform | string | Optional | Any of linkedin, tiktok, pinterest, instagram, facebook, threads, youtube, x. |
| limit | number | Optional | 1 to 100. Default 20. |
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string | Required | History record id. |
| platform | string | Required | Platform the content went to. |
| content_id | string | Required | Platform-side content identifier. |
| title | string | null | Required | Title, when set. |
| description | string | null | Required | Body text, when set. |
| media_url | string | null | Required | Public media URL, when available. |
| media_type | string | null | Required | text, image, or video. |
| status | string | null | Required | Platform-side publish status. |
| created_via | string | Required | x402 for content created through this API. |
| created_at | string | Required | Record creation time. |
curl "https://sharetopus.com/api/x402/history?platform=tiktok&limit=10" \
-H "PAYMENT-SIGNATURE: <signed-payment-payload>"{
"success": true,
"data": {
"history": [
{
"id": "d4c3b2a1-f6e5-4d7c-8b9a-1f2e3d4c5b6a",
"platform": "tiktok",
"content_id": "7361528490123456789",
"title": null,
"description": "Launch day.",
"media_url": "https://...",
"media_type": "video",
"status": "posted",
"created_via": "x402",
"created_at": "2026-06-09T12:04:10.000Z"
}
]
},
"chargeId": "8f0a3c52-7c1e-4b8e-9f21-d4a0c0b6e7aa",
"network": "base",
"txHash": "0x6f2e8a1b...",
"payerAddress": "0x9af31c5e..."
}Four mainnet networks. The API accepts and returns short names; CAIP-2 ids appear inside 402 accepts entries and the PAYMENT-RESPONSE header.
| Network | CAIP-2 id | USDC contract | Decimals |
|---|---|---|---|
| base | eip155:8453 | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 | 6 |
| polygon | eip155:137 | 0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359 | 6 |
| arbitrum | eip155:42161 | 0xaf88d065e77c8cC2239327C5EDb3A432268e5831 | 6 |
| solana | solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp | EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v | 6 |
Settlement runs through the Coinbase CDP facilitator. Select a network per request with ?network=; unknown values return 400 unsupported_network. Default: base.
Current USDC price per action, read live from the pricing table.
| Action | Display name | Price (USDC) | Recurrence |
|---|---|---|---|
| cancel | Cancel a post | 0.001 | one_time |
| connect_account | Connect social acct | 0.5 | one_time |
| delete | Delete post | 0.001 | one_time |
| list_connections | List connections | 0.001 | one_time |
| list_history | List history | 0.001 | one_time |
| list_posts | List posts | 0.001 | one_time |
| post.image | Schedule image post | 0.75 | one_time |
| post.text | Schedule text post | 0.5 | one_time |
| post.video | Schedule video post | 1 | one_time |
| reschedule | Reschedule a post | 0.1 | one_time |
| upload_url | Mint upload URL | 0.1 | one_time |
Prices are returned authoritatively in every 402 response; this table is informational.
Status codes and error codes the surface actually produces. The code is the error field in the response body.
| Status | Code | Meaning |
|---|---|---|
| 400 | validation_error, invalid_json | Body failed schema validation or is not valid JSON. |
| 400 | unsupported_network | ?network is not base, polygon, arbitrum, or solana. |
| 400 | invalid_platform, invalid_post_type, invalid_status, invalid_limit | A query or body enum value is out of range. |
| 400 | malformed_payment, invalid_payment_signature | PAYMENT-SIGNATURE is not valid base64 JSON, or its signature failed verification. |
| 400 | missing_body, malformed_body, siwe_parse_failed | Register verify body is missing, malformed, or unparsable. |
| 401 | missing_authorization, invalid_token, token_expired | Status polling without a valid Bearer connection token. |
| 401 | siwe_domain_mismatch, siwe_address_mismatch, siwe_chain_mismatch, siwe_uri_mismatch, siwe_nonce_invalid, siwe_expired, siwe_not_yet_valid, siwe_invalid_signature | A sign-in field or signature check failed during register. Mismatch bodies carry expected and received. |
| 402 | (payment required) | No payment attached. Body and the PAYMENT-REQUIRED header carry the accepts array. |
| 402 | verify_amount_mismatch, verify_network_mismatch, verify_recipient_mismatch | The signed payment does not match the required amount, network, or recipient. |
| 402 | insufficient_funds | Settlement failed: payer balance too low. |
| 402 | wallet_not_registered | Paying wallet is not registered. Register first. The connect route returns 401 with the same code. |
| 403 | sanctioned | Wallet or payer flagged by sanctions screening. |
| 404 | connection_not_found | The connection token does not match a known connection. |
| 409 | replay, replay_detected | This exact payment was already presented. Sign a fresh payment. |
| 429 | rate_limited, poll_limit_exceeded | Per-IP rate limit hit, or the 720-poll connection cap exhausted. |
| 500 | internal, pricing_not_configured, charge_insert_failed, charge_update_failed | Server-side failure. When the body carries refundInitiated, a settled payment was refunded on-chain. |
| 500 | execution_failed, quota_exceeded, account_not_found, ownership_mismatch, reauth_not_needed | The paid action failed after settlement. The charge is refunded on-chain when possible (refundInitiated true). |
| 502 | facilitator_unavailable | Payment facilitator unreachable or returned an error. |
| 504 | settlement_timeout | Settlement timed out and the outcome may be indeterminate. Do not re-present the same payment; contact support if the charge settled. |
Endpoints wrapped by the shared middleware return { success: false, error, message, chargeId } plus refund fields when applicable. register, connect, and status return { error, ... } without the success field.
{
"success": false,
"error": "insufficient_funds",
"message": "Payer balance is below the required amount.",
"chargeId": null
}{
"error": "siwe_nonce_invalid",
"reason": "already_used"
}Per-IP sliding windows. 429 responses set the Retry-After header; no X-RateLimit headers are sent.
| Scope | Endpoint | Limit | Window |
|---|---|---|---|
| x402_register_challenge | POST /register (challenge) | 10 | 60 s |
| x402_register_verify | POST /register (verify) | 5 | 60 s |
| x402_connect_challenge | POST /connect (challenge) | 10 | 60 s |
| x402_connect_verify | POST /connect (verify) | 5 | 60 s |
| x402_oauth_status_poll | GET /oauth/status | 120 | 60 s |
| x402:reauth | POST /reauth | 10 | 60 s |
| x402:post-now | POST /post-now | 20 | 60 s |
| x402:schedule | POST /schedule | 10 | 60 s |
| x402:upload-url | POST /upload-url | 20 | 60 s |
| x402:reschedule | POST /reschedule | 30 | 60 s |
| x402:cancel | POST /cancel | 30 | 60 s |
| x402:delete | POST /delete | 30 | 60 s |
| x402:connections | GET /connections | 60 | 60 s |
| x402:scheduled-posts | GET /scheduled-posts | 60 | 60 s |
| x402:history | GET /history | 60 | 60 s |
| x402_oauth_callback | GET /api/oauth/callback/<platform> | 60 | 60 s |
All limits are keyed per client IP. Separately, each connection accepts at most 720 status polls over its lifetime (429 poll_limit_exceeded, no Retry-After header). Endpoint handlers also enforce per-wallet limits after settlement; exhausting one returns 500 with the charge refunded on-chain, not a 429.
HTTP/2 429
Retry-After: 42
{
"success": false,
"error": "rate_limited",
"message": "Rate limit exceeded. Please try again later.",
"chargeId": null
}