Buy social media growth with no account
An agent with a USDC wallet, on Base or Solana, finds a service, gets an exact quote, and pays over the x402 protocol right there. No signup, no API key, no OAuth, no deposit: the wallet that signs becomes the account.
Settlement rails
One channel, pick the chain your wallet is already on
The 402 lists a rail for every network the channel currently settles on, each with its own recipient and its own asset id. Nothing bridges between them: a Base wallet and a Solana wallet each pay into their own address, and either one becomes the account that signs it.
- Network
- eip155:8453
- USDC contract
- 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
- Network
- solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp
- USDC mint
- EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
The channel
Facts an agent needs before it pays
| Protocol | x402 v2 |
|---|---|
| Endpoint | POST https://api.growvib.com/v1/agent/orders |
| MCP tool | create_paid_order on https://api.growvib.com/mcp-public |
| Minimum settlement | $1.00A floor on one settlement, not on an order: an order below it is placed at its own price and the remainder stays as spendable balance. |
| Quote lifetime | 300s (maxTimeoutSeconds) |
| Discovery | x402 bazaar extension (extensions.bazaar) |
| Tracking | GET https://api.growvib.com/v1/agent/orders/{order_id} |
Read from the API's live configuration.
Why no account
GrowVib decides what to buy, x402 only settles it
The catalog engine and the recommendation tools pick the right service and option for a goal; the quote prices it server-side. x402 adds one thing: a way for an agent that is nobody's user to pay for that order. The signed payment (an EIP-3009 authorization on Base, a USDC transfer transaction on Solana) is verified and settled by an x402 facilitator, the wallet address becomes a provisional GrowVib account, the settlement is credited to it as an ordinary deposit, and the order is placed from that balance through the same order engine every other channel uses. Refunds, duplicate guards and order history are therefore ordinary too.
The flow
From a goal to a tracked order in one handshake
- 1
Find the service: search_catalog or recommend_service on the anonymous MCP endpoint, or GET /v1/services.
- 2
Quote it: get_quote returns the exact total; its payment_methods.x402 block confirms the order is payable with no account.
- 3
Ask for the price: POST the order with no payment header. The answer is HTTP 402 with one accepts entry per network (Base, and Solana when it is offered), each with the exact amount, asset, recipient and network.
- 4
Sign: pick the entry your wallet is on. On Base, an EIP-3009 transferWithAuthorization for exactly those requirements; on Solana, a USDC transfer of exactly that amount with the 402's feePayer as the fee payer, signed by the wallet only.
- 5
Pay: send the identical request again with the signed payload in PAYMENT-SIGNATURE. The payment is verified, settled on chain, and the order is created.
- 6
Track: GET the order with the agent token the response returned, and spend any remaining balance on the next order without paying again.
curl -i -X POST https://api.growvib.com/v1/agent/orders \ -H "Content-Type: application/json" \ -d '{"service_id":"<service_id from search_catalog>","quantity":1000,"link":"https://www.instagram.com/example"}'1. The request, and the 402 it earns
The body is the same on both requests; only the header differs. The 402 carries the x402 v2 PaymentRequired document twice, base64 in the PAYMENT-REQUIRED header (what libraries read) and as JSON in the body (what a person reads). The amount is in USDC atomic units (6 decimals): 2430000 is $2.43. It is computed on the server from the service, option and quantity; the request carries no price. There is one accepts entry per network the channel settles on, Base first; a client picks the one its wallet can sign.
HTTP/1.1 402 Payment RequiredPAYMENT-REQUIRED: <base64 of the JSON below>Content-Type: application/json{ "x402Version": 2, "error": "Payment is required for this order.", "resource": { "url": "https://api.growvib.com/v1/agent/orders", "description": "Buy social media growth services across Instagram, TikTok, YouTube, Telegram, X ...", "mimeType": "application/json", "serviceName": "GrowVib", "tags": ["social media growth", "SMM", "followers", "Instagram", "Telegram"] }, "accepts": [{ "scheme": "exact", "network": "eip155:8453", "amount": "2430000", "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "payTo": "0x<GrowVib settlement address>", "maxTimeoutSeconds": 300, "extra": { "name": "USD Coin", "version": "2" } }, { "scheme": "exact", "network": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", "amount": "2430000", "asset": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "payTo": "<GrowVib Solana settlement wallet>", "maxTimeoutSeconds": 300, "extra": { "feePayer": "<the facilitator's fee payer>" } }], "extensions": { "bazaar": { "info": { "input": { "type": "http", "method": "POST", "bodyType": "json", "body": { "...": "..." } } }, "schema": { "...": "..." } } }}2. Sign and pay
On Base, sign an EIP-3009 transferWithAuthorization under the EIP-712 domain the 402's extra block names (the token's own name and version; guessing them produces a signature the token refuses), for exactly the amount, asset and recipient it names, with a fresh 32-byte nonce. On Solana, build a USDC transfer of exactly that amount to payTo with the entry's extra.feePayer as the transaction fee payer, sign it with the paying wallet only (the facilitator signs as fee payer and submits it), and send it base64-encoded as payload.transaction; the payer's signature plays the nonce's role. Then send the identical request with the payload base64-encoded in PAYMENT-SIGNATURE. Copy the 402's extensions into the payload as x402 v2 requires; it is not part of what you sign. Any x402 v2 client library does all of this.
# The payload you base64-encode into PAYMENT-SIGNATURE (x402 v2 PaymentPayload):{ "x402Version": 2, "accepted": { ...the accepts entry you chose from the 402, verbatim... }, "payload": { "signature": "0x<65-byte EIP-712 signature>", "authorization": { "from": "0x<your wallet>", "to": "0x<the payTo from the 402>", "value": "2430000", "validAfter": "<unix seconds, a minute ago>", "validBefore": "<unix seconds, within maxTimeoutSeconds>", "nonce": "0x<32 random bytes, hex>" } }, "extensions": { ...the extensions object from the 402, verbatim... }}# On Solana, "accepted" is the solana:... entry and "payload" carries the signed transaction instead:# "payload": { "transaction": "<base64: a USDC transfer of exactly the amount to payTo, fee payer = accepted.extra.feePayer, signed by your wallet only>" }curl -i -X POST https://api.growvib.com/v1/agent/orders \ -H "Content-Type: application/json" \ -H "PAYMENT-SIGNATURE: <base64 of the payload above>" \ -d '{"service_id":"<the same service_id>","quantity":1000,"link":"https://www.instagram.com/example"}'3. The order
201 means the payment settled and the order exists. The PAYMENT-RESPONSE header carries the facilitator's settlement, transaction hash included. Keep the agent_token: it is the credential for tracking this order and for spending whatever balance is left.
HTTP/1.1 201 CreatedPAYMENT-RESPONSE: <base64 JSON: {"success":true,"transaction":"0x<tx hash>","network":"eip155:8453","payer":"0x<your wallet>"}>{ "order_id": "1b2f8e3a-6d1c-4e0f-9b7a-2c3d4e5f6a7b", "tracking_code": "ORD-5G6PG0", "status": "PENDING", "service_id": "<service_id>", "quantity": 1000, "link": "https://www.instagram.com/example", "charged_usd": 2.43, "balance_usd": 0, "payment_id": "9c8b7a6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d", "agent_token": "<bearer token: keep it>", "message": "Payment received and your order has been created."}4. Every other answer, and what to do
Branch on the HTTP status and the status field, never on the message text. Two of these are not failures.
- 402
after paying: the payment was refused before any money moved (wrong amount, expired authorization, insufficient funds). The error field says why in buyer terms. Request a fresh quote and sign again.
- 200
credited_no_order: the payment settled and the order could not be created. The funds are in the wallet's balance. Place the order from balance with the agent_token; do not pay again.
- 202
settlement_unresolved: the settlement was sent and no usable answer came back yet. It is being reconciled. Do not sign a new payment; send the same payload again later and it replays the recorded outcome.
- 409
duplicate_order: this wallet already has a live order for the same service and link. No payment was taken; the body names the existing order. Also the answer to an idempotency_key reused for a different order.
- 400
the request or payload could not be read, or an X-PAYMENT header (x402 v1) was sent.
- 404
unknown service, or the channel is switched off.
- 429
20 requests per minute per IP, Retry-After says when.
5. Spending the balance, and coming back later
The 402 asks for at least the minimum settlement, so a cheap order leaves a remainder as balance. Send the agent_token as Authorization: Bearer with an idempotency_key and no payment header, and the order is placed from balance: nothing on chain, 201. A balance that does not cover the order gets the ordinary 402, and the token also spends a balance a failed order left behind. The token lives one hour and every order refreshes it; a wallet that comes back later signs an ERC-4361 (Sign-In with Ethereum) message, or a Sign-In With Solana message with chain set to solana, instead of paying again.
# A second order paid from the balance the first payment left. Nothing on chain.curl -i -X POST https://api.growvib.com/v1/agent/orders \ -H "Content-Type: application/json" \ -H "Authorization: Bearer <agent_token>" \ -d '{"service_id":"<service_id>","quantity":500,"link":"https://t.me/example","idempotency_key":"<uuid, one per intended order>"}'# A wallet that comes back later: sign in with ERC-4361 instead of paying again.curl -s -X POST https://api.growvib.com/v1/agent/auth/challenge -H "Content-Type: application/json" -d '{"address":"0x<your wallet>"}'# -> {"nonce":"...","message":"<sign these exact bytes with personal_sign>","expires_at":"..."}curl -s -X POST https://api.growvib.com/v1/agent/auth/token -H "Content-Type: application/json" -d '{"nonce":"<nonce>","signature":"0x<signature>"}'# -> {"agent_token":"...","expires_at":"...","address":"0x...","balance_usd":1.57}# A Solana wallet signs in the same way: {"address":"<base58 public key>","chain":"solana"}, sign the message with signMessage, post the signature base58 or hex.6. Tracking
GET the order with the same bearer token (or get_paid_order_status on the anonymous MCP endpoint). Read-only and idempotent, so polling is safe. Statuses: PENDING, SUBMITTED, PROCESSING, COMPLETED, PARTIALLY_COMPLETED, CANCELED, FAILED, PARTIALLY_FAILED, REFUNDED, PARTIALLY_REFUNDED. Another account's order is 404, and a missing or expired token is 401 with the way to get one.
curl -s https://api.growvib.com/v1/agent/orders/1b2f8e3a-6d1c-4e0f-9b7a-2c3d4e5f6a7b \ -H "Authorization: Bearer <agent_token>"{ "order_id": "1b2f8e3a-6d1c-4e0f-9b7a-2c3d4e5f6a7b", "tracking_code": "ORD-5G6PG0", "status": "PROCESSING", "service_name": "Instagram Followers", "quantity": 1000, "link": "https://www.instagram.com/example", "charged_usd": 2.43, "start_count": 1520, "remains": 640, "created_at": "2026-09-10T12:00:00Z", "updated_at": "2026-09-10T12:20:00Z"}# The same handshake over MCP (Streamable HTTP at https://api.growvib.com/mcp-public, no auth):create_paid_order({ service_id, quantity, link }) # -> { status: "payment_required", payment_required: <the 402 document> }create_paid_order({ service_id, quantity, link, payment: <payload> }) # -> { status: "completed", order_id, tracking_code, agent_token, ... }create_paid_order({ service_id, quantity, link, agent_token, idempotency_key }) # -> from balanceget_paid_order_status({ order_id, agent_token })Idempotency, expiry and refunds
The signed nonce (Base) or the payer's transaction signature (Solana) is single-use on chain and unique in GrowVib's ledger, so the same payload sent twice returns the first outcome and settles nothing further; two concurrent copies cannot both settle. A balance order needs an idempotency_key: the same key returns the same order, and the same key with a different service, quantity or link is refused. A quote stays payable for the 402's maxTimeoutSeconds; an authorization past its validBefore is refused without a round trip. An order that cannot be created after a settlement leaves the money as balance, never lost, and an order that later fails or is cancelled is refunded to that same balance through the ordinary refund flow.
Discovery: how agents find this
Every 402 carries the x402 Bazaar discovery extension (extensions.bazaar: an example request, a JSON Schema with a description per field, an example response) and the resource's serviceName, tags and iconUrl, so x402 facilitator catalogs index the resource from the payments that flow through it and an agent searching for what it wants to buy (social media growth, followers, members, views) finds it without knowing the name. The facilitator's verdict on the declaration comes back in an EXTENSION-RESPONSES header on the paying request (bazaar.status of processing, success or rejected with a reason; no header means the client dropped the extension), so a client can tell whether its copy was accepted. One resource, not one per catalog option: the catalog engine chooses the option, x402 settles it. The same facts are on the MCP server card (publicServer.x402), in openapi.json (the Agent payments tag), in the API catalog, in llms.txt, in auth.md and in the x402 agent skill (SKILL.md) on this host.
Security
This is a real-money endpoint and is built like one.
The amount is derived server-side from a fresh quote on every request, and the payload's own accepted block is checked against it, never trusted: a payer cannot name their price, asset, network or recipient.
Settlement happens before any credit or order: a verified-but-unsettled authorization never places an order, so an order can never exist with no money behind it.
Replay is refused at three layers (the on-chain nonce, a unique ledger row per nonce, and the shared order-reservation guard), and a settle whose outcome is unknown is never retried; on Base a reconciler resolves it by re-verifying the authorization, and on Solana, where re-verification cannot decide, it is held for an operator.
No private key is held for the money: the payer signs, the facilitator submits and pays the network fee, and funds land at an address whose keys stay offline. Facilitator reason codes are mapped to buyer copy, never echoed.
The agent token is a short-lived bearer credential scoped to one wallet's account: it can place orders from that balance and read that wallet's orders, and cannot withdraw, refund or change anything. It is not a session, and a session token cannot be used in its place.
Every payment is a ledger row with the payer, network, asset, amounts, facilitator, transaction hash, and the order it produced; requests carry correlation ids; the endpoint is rate limited per IP and the payment path runs under its own request budget.
Questions agents and their developers ask
Does an AI agent need a GrowVib account to pay with x402?
No. There is no signup, API key or OAuth connection. An agent asks for the price, gets an HTTP 402 back, signs the payment, and the wallet that signs becomes the account automatically.
Which blockchains and tokens can an agent pay with?
USDC on Base, and USDC on Solana once the channel offers that rail too. The 402 lists an accepts entry for every network the channel currently settles on, each with its own recipient address, and an agent picks whichever one its wallet is funded on.
Can GrowVib charge more than the price it quoted?
No. The amount comes from a fresh server-side quote on every request, and the signed payment is checked against that exact figure before anything is credited. A payload naming a different amount, asset or recipient is refused before it ever reaches the facilitator.
What happens if the payment settles but the order fails to place?
That response is 200, not an error: the payment already succeeded, so the funds sit as spendable balance on the wallet's new account. The same agent token places the order from that balance with no second payment, and an unspent balance is still there for a different order or an ordinary refund.
How does an agent discover that GrowVib takes x402 payments without being told in advance?
Every 402 carries the x402 Bazaar discovery extension, so facilitator catalogs index this endpoint from the payments that flow through it. The same facts are also published on the MCP server card, in openapi.json, in llms.txt and in auth.md, so an agent reading any one of those learns the endpoint, the networks and the asset before it ever sends a request.
Machine-readable and related
- OpenAPI (the Agent payments tag documents every status)
https://api.growvib.com/openapi.json
- MCP server card (publicServer.x402 while enabled)
https://api.growvib.com/.well-known/mcp/server-card.json
- API catalog (RFC 9727)
https://api.growvib.com/.well-known/api-catalog
- llms.txt (the agent guide)
https://growvib.com/llms.txt
- auth.md (every access level)
https://growvib.com/auth.md
- x402 agent skill (SKILL.md)
https://growvib.com/.well-known/agent-skills/growvib-x402/SKILL.md
- The MCP server for connected accounts
https://growvib.com/mcp
Point your agent at the anonymous MCP endpoint
Catalog search, recommendations and exact quotes are free. When it is time to buy, the same endpoint takes the payment.