Homex402 API Reference

x402 API Reference

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.

Base URL: https://sharetopus.com/api/x402basepolygonarbitrumsolana
All four networks are mainnet. Every paid call settles real USDC. There is no test mode on this surface; start with the cheapest actions (see Pricing) while integrating.

Payment flow

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.

  1. 1
    Register your wallet once.

    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.

  2. 2
    Call a paid endpoint with no payment.

    Send the request as if the API were free. Pick a network with ?network= (default: base).

  3. 3
    Read the 402.

    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.

  4. 4
    Sign the payment.

    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.

  5. 5
    Retry with PAYMENT-SIGNATURE.

    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.

  6. 6
    The server verifies, settles, then executes.

    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).

  7. 7
    For social accounts: finish OAuth.

    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.

Response · 402
{
  "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"
}
Quickstart · cURL
# 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" }'
Response · 200 · Envelope
{
  "success": true,
  "data": { "...": "endpoint-specific result, see each endpoint" },
  "chargeId": "8f0a3c52-7c1e-4b8e-9f21-d4a0c0b6e7aa",
  "network": "base",
  "txHash": "0x6f2e8a1b...",
  "payerAddress": "0x9af31c5e..."
}
Settlement Headers
HTTP/2 200
PAYMENT-RESPONSE: <base64>
X-PAYMENT-RESPONSE: <base64>

# decoded PAYMENT-RESPONSE
{
  "success": true,
  "payer": "0x9af31c5e...",
  "transaction": "0x6f2e8a1b...",
  "network": "eip155:8453",
  "amount": "750000"
}
Each signed payment is single use. Presenting the same payment twice returns 409 replay. Sign a fresh payment for every call.

Wallet registration

One-time onboarding, itself paid (the register action). The same POST route serves the challenge (no payment header) and the verify (payment header present).

POST

Request a registration challenge

/api/x402/register

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.

Query Parameters
ParameterTypeRequiredDescription
networkstringOptionalPayment network: base, polygon, arbitrum, or solana. Default base. Unknown values return 400 unsupported_network.
Example Request
curl -X POST "https://sharetopus.com/api/x402/register?network=base"
Response · 402
{
  "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"
  }
}
POST

Verify and register

/api/x402/register

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.

Request Body
ParameterTypeRequiredDescription
siweMessagestringRequiredThe 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.
siweSignaturestringRequiredEVM: hex signature, 0x-prefixed. Solana: base58 Ed25519 signature.
Response Fields
ParameterTypeRequiredDescription
principalIdstringRequiredWallet principal id, format wallet_<32 hex chars>.
walletIdstringRequiredSame value as principalId.
addressstringRequiredRegistered wallet address. EVM addresses are stored lowercase; Solana addresses keep their casing.
chainstringRequiredbase, polygon, arbitrum, or solana.
sanctionsStatusstringRequiredclean for fresh registrations.
isNewbooleanRequiredfalse when the wallet was already registered.
chargeIdstring | nullRequiredCharge id for this registration. Null when isNew is false.
Keep your wallet key offline. The API never needs the key, only signatures: one sign-in signature to prove wallet ownership at registration and one payment signature per paid call.
Re-registering an existing wallet returns 200 with isNew false and charges nothing. The unclaimed payment authorization simply expires.
Example Request
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..."
  }'
Response · 200
{
  "principalId": "wallet_2f6a1c0e9b8d4a7f5c3e1d2b4a6c8e0f",
  "walletId": "wallet_2f6a1c0e9b8d4a7f5c3e1d2b4a6c8e0f",
  "address": "0x9af31c5e...",
  "chain": "base",
  "sanctionsStatus": "clean",
  "isNew": true,
  "chargeId": "8f0a3c52-7c1e-4b8e-9f21-d4a0c0b6e7aa"
}

Connect a social account

Paid OAuth initiation for linkedin, tiktok, pinterest, and instagram. No request body: the wallet is identified by the payment signature alone.

POST

Request connect requirements

/api/x402/connect

Call with ?platform and no PAYMENT-SIGNATURE header. Returns 402 quoting the connect_account price. No SIWE nonce here; the wallet is already registered.

Query Parameters
ParameterTypeRequiredDescription
platformstringRequiredOne of linkedin, tiktok, pinterest, instagram. Anything else returns 400 invalid_platform.
networkstringOptionalbase, polygon, arbitrum, or solana. Default base.
Example Request
curl -X POST "https://sharetopus.com/api/x402/connect?platform=tiktok"
Response · 402
{
  "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" }
    }
  ]
}
POST

Pay and get the OAuth URL

/api/x402/connect

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.

Response Fields
ParameterTypeRequiredDescription
connectionIdstringRequiredId of the pending connection.
platformstringRequiredEchoes the requested platform.
oauthUrlstring | nullRequiredAuthorization URL to open in a browser. Null on idempotent reconnects.
connectionTokenstring | nullRequiredOpaque 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.
expiresAtstringRequiredISO timestamp. New connections expire 15 minutes after creation.
isReconnectbooleanRequiredTrue when an existing healthy connection was returned instead of starting OAuth.
Reconnecting an already-connected account returns oauthUrl null, does not start a new OAuth flow, and charges nothing.
Example Request
curl -X POST "https://sharetopus.com/api/x402/connect?platform=tiktok" \
  -H "PAYMENT-SIGNATURE: <signed-payment-payload>"
Response · 200
{
  "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
}

Poll connection status

Free polling endpoint. The connection token is the only credential.

pendingconnected
terminal alternatives:expiredfailedrevoked
GET

Poll connection status

/api/x402/oauth/status

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.

Headers
ParameterTypeRequiredDescription
AuthorizationstringRequiredBearer <connectionToken>.
Response Fields
ParameterTypeRequiredDescription
connectionIdstringRequiredConnection being polled.
platformstringRequiredOAuth platform.
statusstringRequiredpending, connected, expired, failed, or revoked.
connectedAtstring | nullRequiredSet when status reaches connected.
expiresAtstringRequiredWhen the pending connection stops being claimable.
socialAccountIdstring | nullRequiredThe connected account id, usable with post endpoints once set.
pollCountnumberRequiredPoll count after this request, toward the 720 cap.
errorCodestring | nullRequiredSet when the OAuth flow failed.
errorMessagestring | nullRequiredHuman-readable failure detail.
Example Request
curl "https://sharetopus.com/api/x402/oauth/status" \
  -H "Authorization: Bearer v1.eyJjb25uZWN0aW9uSWQiOiAi...In0.5rT9vQ..."
Response · 200
{
  "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
}
Response · 429
{
  "error": "poll_limit_exceeded",
  "message": "Poll limit reached for this connection (720)."
}

Reauthorize a connection

Re-authenticate an expired social connection. Paid, same connect_account action as connect.

POST

Reauthorize a connection

/api/x402/reauth

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.

Request Body
ParameterTypeRequiredDescription
social_account_idstring (uuid)RequiredAccount id from GET /api/x402/connections.
Response Fields (data)
ParameterTypeRequiredDescription
connectionIdstringRequiredNew pending connection id.
platformstringRequiredPlatform of the account.
oauthUrlstringRequiredAuthorization URL to open in a browser.
connectionTokenstringRequiredBearer token for status polling.
expiresAtstringRequired15 minutes after creation.
Example Request
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" }'
Response · 200
{
  "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..."
}

Post now

Publish immediately to one connected account. The price follows the post type.

POST

Create a post

/api/x402/post-now

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.

Request Body
ParameterTypeRequiredDescription
social_account_idstring (uuid)RequiredConnected account to post from.
platformstringRequiredlinkedin, tiktok, pinterest, or instagram. Must match the account.
post_typestringRequiredtext, image, or video. Selects the pricing action.
descriptionstring | nullRequiredPost body text. The key is required; the value may be null.
media_storage_pathstringOptionalRequired for image and video posts. The path returned by POST /api/x402/upload-url.
titlestring | nullOptionalPost title where the platform supports one.
cover_timestampnumberOptionalVideo cover frame timestamp.
pinterest_board_idstringOptionalPinterest board id.
pinterest_board_namestringOptionalPinterest board name.
pinterest_linkstringOptionalOutbound link for Pinterest pins.
idempotency_keystringOptionalClient-supplied key to dedupe retries.
Response Fields (data)
ParameterTypeRequiredDescription
batchIdstringRequiredBatch identifier for this dispatch.
eventIdsstring[]RequiredIds of the dispatched posting jobs.
dispatchednumberRequiredCount of jobs dispatched.
Example Request
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"
  }'
Response · 200
{
  "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..."
}

Schedule a post

Same body as post-now plus a future timestamp.

POST

Schedule a post

/api/x402/schedule

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.

Request Body (in addition to post-now fields)
ParameterTypeRequiredDescription
scheduled_atstringRequiredISO 8601 datetime. Must parse and be in the future.
post_optionsobject | nullOptionalPer-platform options object passed through to the scheduler.
Response Fields (data)
ParameterTypeRequiredDescription
batchIdstringRequiredBatch identifier for this schedule call.
scheduleIdsstring[]RequiredIds of the created scheduled posts. Use them with reschedule, cancel, and delete.
insertednumberRequiredCount of posts stored.
Example Request
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"
  }'
Response · 200
{
  "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..."
}

Upload media

Mint a signed upload URL for post media.

POST

Create an upload URL

/api/x402/upload-url

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.

Request Body
ParameterTypeRequiredDescription
filenamestringRequired1 to 255 characters.
content_typestringRequiredMIME type of the file.
size_bytesnumberRequiredPositive integer. Max 262144000 (250 MB) per file.
Response Fields (data)
ParameterTypeRequiredDescription
uploadUrlstringRequiredSigned upload URL.
pathstringRequiredStorage path to use as media_storage_path in post-now and schedule.
Example Request
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 }'
Response · 200
{
  "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..."
}

Manage scheduled posts

Move, cancel, or hard-delete scheduled posts. The batch endpoints accept 1 to 50 ids per call.

POST

Reschedule a post

/api/x402/reschedule

Charges reschedule. Moves one scheduled post to a new future time.

Request Body
ParameterTypeRequiredDescription
post_idstring (uuid)RequiredScheduled post to move.
new_scheduled_timestringRequiredISO 8601 datetime. Must be in the future.
Response Fields (data)
ParameterTypeRequiredDescription
succeedednumberRequiredPosts moved.
resumednumberRequiredPreviously paused posts resumed by the move.
Example Request
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"
  }'
Response · 200
{
  "success": true,
  "data": { "succeeded": 1, "resumed": 0 },
  "chargeId": "8f0a3c52-7c1e-4b8e-9f21-d4a0c0b6e7aa",
  "network": "base",
  "txHash": "0x6f2e8a1b...",
  "payerAddress": "0x9af31c5e..."
}
POST

Cancel scheduled posts

/api/x402/cancel

Charges cancel. Cancels 1 to 50 scheduled posts owned by the wallet. Cancelled posts keep their row and media.

Request Body
ParameterTypeRequiredDescription
post_idsstring[] (uuid)Required1 to 50 scheduled post ids.
Response Fields (data)
ParameterTypeRequiredDescription
succeedednumberRequiredPosts cancelled.
failednumberRequiredPosts that could not be cancelled.
Example Request
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"] }'
Response · 200
{
  "success": true,
  "data": { "succeeded": 1, "failed": 0 },
  "chargeId": "8f0a3c52-7c1e-4b8e-9f21-d4a0c0b6e7aa",
  "network": "base",
  "txHash": "0x6f2e8a1b...",
  "payerAddress": "0x9af31c5e..."
}
POST

Delete posts

/api/x402/delete

Charges delete. Hard deletes 1 to 50 scheduled or completed posts and their stored media. Not reversible.

Request Body
ParameterTypeRequiredDescription
post_idsstring[] (uuid)Required1 to 50 post ids.
Response Fields (data)
ParameterTypeRequiredDescription
succeedednumberRequiredPosts deleted.
failednumberRequiredPosts that could not be deleted.
mediaDeletednumberRequiredMedia files removed from storage.
Example Request
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"] }'
Response · 200
{
  "success": true,
  "data": { "succeeded": 1, "failed": 0, "mediaDeleted": 1 },
  "chargeId": "8f0a3c52-7c1e-4b8e-9f21-d4a0c0b6e7aa",
  "network": "base",
  "txHash": "0x6f2e8a1b...",
  "payerAddress": "0x9af31c5e..."
}

Read endpoints

Paid GET endpoints. The payment signature authenticates the wallet; the 402 flow is the same as for POST routes.

GET

List connected accounts

/api/x402/connections

Charges list_connections. Returns the wallet's connected social accounts. Platform tokens are never included.

Query Parameters
ParameterTypeRequiredDescription
include_unavailablestringOptionaltrue to include accounts whose platform token expired (candidates for reauth). Default: only available accounts.
Response Fields (data.accounts[])
ParameterTypeRequiredDescription
idstringRequiredAccount id, used as social_account_id elsewhere.
platformstringRequiredSocial platform of the account.
display_namestring | nullRequiredProfile display name.
usernamestring | nullRequiredProfile handle.
avatar_urlstring | nullRequiredProfile image URL.
is_availablebooleanRequiredFalse when the platform token expired; use reauth.
follower_countnumber | nullRequiredFollower count at last sync.
Example Request
curl "https://sharetopus.com/api/x402/connections?include_unavailable=true" \
  -H "PAYMENT-SIGNATURE: <signed-payment-payload>"
Response · 200
{
  "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..."
}
GET

List scheduled posts

/api/x402/scheduled-posts

Charges list_posts. Returns the wallet's scheduled posts.

Query Parameters
ParameterTypeRequiredDescription
statusstringOptionalscheduled, queued, processing, posted, failed, or cancelled.
platformstringOptionalFilter by platform.
limitnumberOptional1 to 100. Default 20.
Response Fields (data.posts[])
ParameterTypeRequiredDescription
idstringRequiredScheduled post id.
scheduled_atstringRequiredPublish time, ISO 8601.
statusstringRequiredscheduled, queued, processing, posted, failed, or cancelled.
platformstringRequiredTarget platform.
post_titlestring | nullRequiredTitle, when set.
post_descriptionstring | nullRequiredBody text, when set.
media_typestringRequiredtext, image, or video.
media_storage_pathstringRequiredStorage path of the attached media.
error_messagestring | nullRequiredSet when publishing failed.
batch_idstring | nullRequiredBatch the post was created in.
created_viastringRequiredx402 for posts created through this API.
Example Request
curl "https://sharetopus.com/api/x402/scheduled-posts?status=scheduled&limit=20" \
  -H "PAYMENT-SIGNATURE: <signed-payment-payload>"
Response · 200
{
  "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..."
}
GET

List content history

/api/x402/history

Charges list_history. Returns published content records for the wallet.

Query Parameters
ParameterTypeRequiredDescription
platformstringOptionalAny of linkedin, tiktok, pinterest, instagram, facebook, threads, youtube, x.
limitnumberOptional1 to 100. Default 20.
Response Fields (data.history[])
ParameterTypeRequiredDescription
idstringRequiredHistory record id.
platformstringRequiredPlatform the content went to.
content_idstringRequiredPlatform-side content identifier.
titlestring | nullRequiredTitle, when set.
descriptionstring | nullRequiredBody text, when set.
media_urlstring | nullRequiredPublic media URL, when available.
media_typestring | nullRequiredtext, image, or video.
statusstring | nullRequiredPlatform-side publish status.
created_viastringRequiredx402 for content created through this API.
created_atstringRequiredRecord creation time.
Example Request
curl "https://sharetopus.com/api/x402/history?platform=tiktok&limit=10" \
  -H "PAYMENT-SIGNATURE: <signed-payment-payload>"
Response · 200
{
  "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..."
}

Networks and assets

Four mainnet networks. The API accepts and returns short names; CAIP-2 ids appear inside 402 accepts entries and the PAYMENT-RESPONSE header.

NetworkCAIP-2 idUSDC contractDecimals
baseeip155:84530x833589fCD6eDb6E08f4c7C32D4f71b54bdA029136
polygoneip155:1370x3c499c542cEF5E3811e1192ce70d8cC03d5c33596
arbitrumeip155:421610xaf88d065e77c8cC2239327C5EDb3A432268e58316
solanasolana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpEPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v6

Settlement runs through the Coinbase CDP facilitator. Select a network per request with ?network=; unknown values return 400 unsupported_network. Default: base.

Pricing

Current USDC price per action, read live from the pricing table.

ActionDisplay namePrice (USDC)Recurrence
cancelCancel a post0.001one_time
connect_accountConnect social acct0.5one_time
deleteDelete post0.001one_time
list_connectionsList connections0.001one_time
list_historyList history0.001one_time
list_postsList posts0.001one_time
post.imageSchedule image post0.75one_time
post.textSchedule text post0.5one_time
post.videoSchedule video post1one_time
rescheduleReschedule a post0.1one_time
upload_urlMint upload URL0.1one_time

Prices are returned authoritatively in every 402 response; this table is informational.

Error codes

Status codes and error codes the surface actually produces. The code is the error field in the response body.

StatusCodeMeaning
400validation_error, invalid_jsonBody failed schema validation or is not valid JSON.
400unsupported_network?network is not base, polygon, arbitrum, or solana.
400invalid_platform, invalid_post_type, invalid_status, invalid_limitA query or body enum value is out of range.
400malformed_payment, invalid_payment_signaturePAYMENT-SIGNATURE is not valid base64 JSON, or its signature failed verification.
400missing_body, malformed_body, siwe_parse_failedRegister verify body is missing, malformed, or unparsable.
401missing_authorization, invalid_token, token_expiredStatus polling without a valid Bearer connection token.
401siwe_domain_mismatch, siwe_address_mismatch, siwe_chain_mismatch, siwe_uri_mismatch, siwe_nonce_invalid, siwe_expired, siwe_not_yet_valid, siwe_invalid_signatureA 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.
402verify_amount_mismatch, verify_network_mismatch, verify_recipient_mismatchThe signed payment does not match the required amount, network, or recipient.
402insufficient_fundsSettlement failed: payer balance too low.
402wallet_not_registeredPaying wallet is not registered. Register first. The connect route returns 401 with the same code.
403sanctionedWallet or payer flagged by sanctions screening.
404connection_not_foundThe connection token does not match a known connection.
409replay, replay_detectedThis exact payment was already presented. Sign a fresh payment.
429rate_limited, poll_limit_exceededPer-IP rate limit hit, or the 720-poll connection cap exhausted.
500internal, pricing_not_configured, charge_insert_failed, charge_update_failedServer-side failure. When the body carries refundInitiated, a settled payment was refunded on-chain.
500execution_failed, quota_exceeded, account_not_found, ownership_mismatch, reauth_not_neededThe paid action failed after settlement. The charge is refunded on-chain when possible (refundInitiated true).
502facilitator_unavailablePayment facilitator unreachable or returned an error.
504settlement_timeoutSettlement 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.

Error Response Format
{
  "success": false,
  "error": "insufficient_funds",
  "message": "Payer balance is below the required amount.",
  "chargeId": null
}
Error Format · register / connect / status
{
  "error": "siwe_nonce_invalid",
  "reason": "already_used"
}

Rate limits

Per-IP sliding windows. 429 responses set the Retry-After header; no X-RateLimit headers are sent.

ScopeEndpointLimitWindow
x402_register_challengePOST /register (challenge)1060 s
x402_register_verifyPOST /register (verify)560 s
x402_connect_challengePOST /connect (challenge)1060 s
x402_connect_verifyPOST /connect (verify)560 s
x402_oauth_status_pollGET /oauth/status12060 s
x402:reauthPOST /reauth1060 s
x402:post-nowPOST /post-now2060 s
x402:schedulePOST /schedule1060 s
x402:upload-urlPOST /upload-url2060 s
x402:reschedulePOST /reschedule3060 s
x402:cancelPOST /cancel3060 s
x402:deletePOST /delete3060 s
x402:connectionsGET /connections6060 s
x402:scheduled-postsGET /scheduled-posts6060 s
x402:historyGET /history6060 s
x402_oauth_callbackGET /api/oauth/callback/<platform>6060 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.

Response · 429
HTTP/2 429
Retry-After: 42

{
  "success": false,
  "error": "rate_limited",
  "message": "Rate limit exceeded. Please try again later.",
  "chargeId": null
}