Service JSON
A service is described by one JSON object. Use it with the Import JSON button on the Gateway dashboard (paste or upload a file) to create one or many services at once, or with Edit all (JSON) to bulk-edit a service's endpoints. You can pass a single object or an array of them.
Limits: each account may create up to 5 services, and each service up to 50 endpoints. Payments settle to the payTo you set in Settings (per account) unless a service sets its own payTo.
Full example
[
{
"name": "Weather API",
"upstreamBaseUrl": "https://api.weather.example.com",
"description": "Current conditions and forecast for any city.",
"tags": ["weather", "data"],
"enabled": true,
"auth": { "method": "bearer", "secret": "sk_live_your_upstream_key" },
"routes": [
{ "method": "GET", "path": "/v1/current/:city", "priceUSDC": "0.01", "capability": "current weather", "enabled": true },
{ "method": "GET", "path": "/v1/forecast/:city", "priceUSDC": "0.02", "capability": "7-day forecast" },
{ "method": "GET", "path": "/v1/health", "priceUSDC": "0", "capability": "free health check" }
]
}
]
Service fields
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | yes | Display name of the service. |
upstreamBaseUrl | string (URL) | yes | Your API base URL. Endpoint paths are appended to this. Must be a public https host. |
description | string | no | Shown to agents. Max 2000 chars. |
tags | string[] | no | Discovery tags. Max 20. |
payTo | string (0x address) | no | Per-service override of where USDC settles. Defaults to the payTo you set in Settings. |
enabled | boolean | no | Defaults to true. A disabled service serves no endpoints (503). |
isPublic | boolean | no | Defaults to false. When true, the service is listed in the public marketplace so agents can discover it (also toggled by Make public on the service page). |
auth | object | no | How the platform authenticates to your upstream. Defaults to { "method": "none" }. |
routes | object[] | no | The charge endpoints. Can be empty and added later. Max 50. |
Auth methods
The auth.method selects how your upstream credential is injected on every forwarded request. The secret is stored encrypted at rest and never returned by the API.
method | Extra fields | Injected as |
|---|---|---|
none | - | No credential. |
bearer | secret | Authorization: Bearer <secret> |
api_key_header | headerName, secret | <headerName>: <secret> |
api_key_query | queryParam, secret | ?<queryParam>=<secret> on the upstream URL |
basic | username, secret | Authorization: Basic base64(username:secret) |
custom_header | headerName, secret | <headerName>: <secret> (fixed value) |
Example (API key in a header):
"auth": { "method": "api_key_header", "headerName": "X-API-Key", "secret": "your_key" }
When editing an existing service, omit secret to keep the stored one.
Route fields
Each entry in routes is one charge endpoint.
| Field | Type | Required | Notes |
|---|---|---|---|
method | string | yes | One of GET, POST, PUT, PATCH, DELETE. |
path | string | yes | Incoming path under the service, starting with /. Supports :param segments, e.g. /v1/node/:address/status. |
priceUSDC | string | yes | Price as a decimal string, e.g. "0.01". Use "0" for a free (unpaid) route. |
capability | string | no | Short label shown in the dashboard and on the 402 challenge. |
upstreamPath | string | no | Upstream path if it differs from path. Same :param names. Defaults to path. |
enabled | boolean | no | Defaults to true. A disabled endpoint returns 404. |
Calling an endpoint
Once created, an endpoint is reachable at:
https://api.xdcai.tech/x402/connect/<serviceId>/<path>
A paid endpoint returns HTTP 402 with a payment challenge; an x402 agent or the XDC AI CLI settles it in USDC, gaslessly. A free endpoint (priceUSDC of "0") is proxied straight through.