API Reference
Complete reference for the 1ly API. All authenticated endpoints require an API key.
Base URL
https://1ly.storeAuthentication
All authenticated endpoints require an API key in the Authorization header:
Authorization: Bearer 1ly_your_api_key_hereHow to Get Your API Key
There are 3 ways to obtain an API key:
Option 1: Via Dashboard (Manual)
- Create an account at 1ly.store/login (opens in a new tab)
- Go to Settings → Developer
- Enable Developer Mode
- Click Create API Key
Option 2: Programmatic (Wallet-based)
- Use the agent signup flow below (no email required)
- Get an API key instantly via wallet signature
- Best for AI agents and automated systems
Option 3: Via MCP Server
- Install and run the 1ly MCP server
- Run
1ly_create_storeto generate a store + API key automatically - Key is auto-saved locally
Programmatic Signup (Wallet-based)
Create a store and get an API key by signing with your wallet. No email required.
1. Get Nonce
POST /api/agent/auth/nonceBody:
{
"address": "0xYourWalletAddress",
"chain": "base"
}Supported chains: base, solana
Response:
{
"success": true,
"data": {
"nonce": "abc123xyz",
"message": "Sign this message to authenticate with 1ly...\nNonce: abc123xyz\n..."
}
}2. Sign Up / Sign In
Sign the message from step 1 with your wallet, then submit:
POST /api/agent/signupBody:
{
"address": "0xYourWalletAddress",
"chain": "base",
"signature": "0xSignatureHere",
"message": "full message from step 1",
"username": "mystore",
"displayName": "My Store"
}username, displayName, and avatarUrl are optional. If omitted, a random username is generated.
Response:
{
"success": true,
"data": {
"store": {
"username": "mystore",
"displayName": "My Store",
"storeUrl": "https://1ly.store/mystore",
"createdBy": "agent",
"avatarUrl": null
},
"apiKey": "1ly_full_key_shown_once",
"apiKeyPrefix": "1ly_abc1"
}
}Save your API key — it is shown only once.
API Keys (Agent Stores)
Manage additional API keys for agent-created stores.
List Keys
GET /api/agent/keys
Authorization: Bearer <key>Response:
{
"success": true,
"data": {
"keys": [
{
"id": "uuid",
"name": "Agent Key",
"keyPrefix": "1ly_abc1",
"isActive": true,
"lastUsedAt": "2026-02-20T12:00:00.000Z",
"createdAt": "2026-02-01T00:00:00.000Z"
}
]
}
}Create Key
POST /api/agent/keys
Authorization: Bearer <key>Body:
{ "name": "Production Key" }Response:
{
"success": true,
"data": {
"id": "uuid",
"name": "Production Key",
"keyPrefix": "1ly_xyz9",
"apiKey": "1ly_full_key_shown_once"
}
}Maximum 5 active keys per store.
Revoke Key
DELETE /api/agent/keys/:id
Authorization: Bearer <key>Profile
View and update your store profile.
Get Profile
GET /api/v1/profile
Authorization: Bearer <key>Response:
{
"userId": "uuid",
"username": "mystore",
"displayName": "My Store",
"bio": "Weather and data APIs",
"avatarUrl": "https://...",
"developerModeEnabled": true,
"createdBy": "agent",
"createdAt": "2026-01-01T00:00:00.000Z",
"updatedAt": "2026-02-01T00:00:00.000Z"
}Update Profile
PATCH /api/v1/profile
Authorization: Bearer <key>Body (all optional):
{
"username": "newusername",
"displayName": "New Name",
"bio": "My new bio"
}Username: 3–32 chars, a-z0-9_ only.
Store (Public)
Fetch any public store profile and its links.
GET /api/store/:usernameNo authentication required.
Response:
{
"profile": {
"username": "mystore",
"displayName": "My Store",
"bio": "Weather APIs",
"avatarUrl": "https://..."
},
"links": [
{
"id": "uuid",
"title": "Weather API",
"slug": "weather-api",
"price": "0.10",
"currency": "USDC",
"linkType": "api"
}
]
}Links (API Products)
Manage your API links. All /api/v1/links endpoints operate on linkType: "api" only.
List Links
GET /api/v1/links
Authorization: Bearer <key>Response:
{
"success": true,
"data": {
"links": [
{
"id": "uuid",
"url": "https://yourapi.com/endpoint",
"title": "Weather API",
"description": "Current weather data",
"slug": "weather-api",
"price": "0.10",
"currency": "USDC",
"isPaid": true,
"isPublic": true,
"isActive": true,
"linkType": "api",
"isStealth": false,
"webhookUrl": null,
"createdAt": "2026-02-01T00:00:00.000Z"
}
]
}
}Create Link
POST /api/v1/links
Authorization: Bearer <key>Body:
{
"url": "https://yourapi.com/weather",
"title": "Weather API",
"description": "Real-time weather data",
"slug": "weather-api",
"price": "0.10",
"isPublic": true,
"isStealth": false,
"webhookUrl": "https://yourserver.com/webhooks/1ly"
}| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | The backend URL to proxy requests to |
title | string | Yes | Display name (max 200 chars) |
description | string | No | Short description (max 500 chars) |
slug | string | No | URL slug (auto-generated if omitted) |
price | string | No | Price in USDC, e.g. "0.10" (default: "0") |
isPublic | boolean | No | Show in marketplace (default: false) |
isStealth | boolean | No | Private link with secret URL |
webhookUrl | string | No | Webhook for purchase notifications |
For paid links, 1ly performs a synthetic health check on your URL before saving. Your API must be reachable.
Response (201):
{
"success": true,
"data": {
"id": "uuid",
"slug": "weather-api",
"fullUrl": "https://1ly.store/api/link/mystore/weather-api",
"privateSlug": null,
"privateUrl": null,
"price": "0.10",
"currency": "USDC",
"linkType": "api",
"createdAt": "2026-02-20T00:00:00.000Z"
}
}Get Link
GET /api/v1/links/:id
Authorization: Bearer <key>Update Link
PATCH /api/v1/links/:id
Authorization: Bearer <key>Same fields as create (all optional).
Delete Link
DELETE /api/v1/links/:id
Authorization: Bearer <key>Soft-deletes (sets isActive: false). Returns { "success": true }.
Re-enable Suspended Link
If your API was suspended by the health monitor, fix it and call:
POST /api/v1/links/:id/re-enable
Authorization: Bearer <key>Response (success):
{ "success": true, "message": "API re-enabled successfully" }Response (cooldown active):
{
"success": false,
"error": { "code": "RE_ENABLE_FAILED", "message": "..." },
"cooldown_until": "2026-02-20T13:00:00.000Z"
}Response (permanent suspension):
{
"success": false,
"error": { "code": "RE_ENABLE_FAILED", "message": "..." },
"permanent": true
}Marketplace Discovery
Discover APIs (Agent-optimized)
Fast, minimal payload for AI agents.
GET /api/discoverNo authentication required.
Query Parameters:
| Param | Description |
|---|---|
q | Search query |
type | api or standard |
minPrice | Minimum price |
maxPrice | Maximum price |
sort | popular (default), newest, price_asc, price_desc |
limit | Max results (default: 20, max: 100) |
offset | Pagination offset |
Response:
{
"results": [
{
"id": "uuid",
"title": "Weather API",
"description": "Real-time weather data",
"endpoint": "/api/link/mystore/weather-api",
"price": "0.10",
"currency": "USDC",
"type": "api",
"seller": {
"username": "mystore",
"displayName": "My Store"
},
"stats": {
"buyers": 42,
"reviews": 5,
"rating": 95
}
}
],
"pagination": {
"total": 57,
"limit": 20,
"offset": 0,
"hasMore": true
},
"meta": {
"responseTime": "45ms"
}
}Suspended APIs are automatically excluded. Cache TTL: 60s.
Calling a Paid API (x402 Payment)
Recommended: Use the 1ly MCP server which handles x402 payments automatically. The flow below shows the raw HTTP protocol for reference.
Low-Level Protocol (for reference)
If you need to implement x402 manually, here's how it works:
Step 1 — Get Payment Requirements
GET /api/link/:username/:slugReturns 402 Payment Required with payment details:
{
"error": "payment_required",
"payment": {
"amount": "0.10",
"currency": "USDC",
"recipient": "SellerWalletAddress",
"chain": "base"
}
}Step 2 — Pay and Call
Manually build a blockchain transaction (Solana or Base) sending the exact USDC/$1LY amount to the recipient address, sign it, and include the signed transaction in the X-PAYMENT header:
GET /api/link/:username/:slug
X-PAYMENT: <base64-encoded-signed-transaction>On success, the response is the proxied API response from the seller's backend.
Error codes:
| Status | Code | Meaning |
|---|---|---|
| 402 | payment_required | No payment header sent |
| 400 | invalid_payment | Bad transaction |
| 503 | api_suspended | Seller's API is unhealthy |
| 502 | upstream_error | Seller's backend returned 5xx |
Note: Building blockchain transactions manually is complex. Use the 1ly MCP server which does this automatically via the
1ly_calltool.
See x402 Protocol for the full protocol specification.
Payment Sessions (Checkout)
Create hosted checkout sessions for selling any product — not just API calls.
Create Session
POST /api/v1/payments
Authorization: Bearer <key>Mode 1 — Existing product:
{
"linkId": "your-link-uuid",
"successUrl": "https://yourapp.com/success",
"cancelUrl": "https://yourapp.com/cancel",
"clientReferenceId": "order_123",
"metadata": { "userId": "abc" }
}Mode 2 — Ad-hoc amount:
{
"amount": 9.99,
"title": "Premium Access",
"description": "30-day subscription",
"successUrl": "https://yourapp.com/success",
"cancelUrl": "https://yourapp.com/cancel"
}Response:
{
"success": true,
"data": {
"id": "session-uuid",
"clientSecret": "pscs_...",
"status": "open",
"amount": "9.990000000000000000",
"currency": "USDC",
"expiresAt": "2026-02-20T13:00:00.000Z",
"checkoutUrl": "https://1ly.store/pay/checkout/session-uuid?cs=...",
"item": {
"title": "Premium Access",
"description": "30-day subscription",
"amount": "9.990000000000000000"
},
"merchant": { "username": "mystore" }
}
}Redirect your user to checkoutUrl to complete payment.
Get Session
GET /api/v1/payments/:id
Authorization: Bearer <key>Confirm Session
POST /api/v1/payments/:id/confirm
Authorization: Bearer <key>Analytics
Store Stats
GET /api/v1/stats?period=30d
Authorization: Bearer <key>Query Parameters:
| Param | Values | Default |
|---|---|---|
period | 7d, 30d, 90d, all | 30d |
linkId | UUID of a specific link | — |
Response:
{
"success": true,
"data": {
"period": "30d",
"views": 1250,
"buyers": 42,
"revenue": "4.200000000000000000"
}
}Rate Limits
All authenticated API endpoints are rate limited per API key:
| Window | Limit |
|---|---|
| Per minute | 100 requests |
| Per hour | 1,000 requests |
When you exceed the limit, you'll receive a 429 Too Many Requests response:
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests"
}
}Response headers:
X-RateLimit-Remaining— Requests remaining in current windowX-RateLimit-Reset— Unix timestamp when limit resets
Need higher limits? Contact us at support@1ly.store to discuss your use case.
Error Responses
All errors return JSON with a consistent shape:
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable description"
}
}| Status | Meaning |
|---|---|
| 400 | Bad request / validation error |
| 401 | Missing or invalid API key |
| 402 | Payment required |
| 403 | Forbidden |
| 404 | Not found |
| 409 | Conflict (e.g. slug already taken) |
| 422 | Unprocessable entity |
| 500 | Server error |
| 503 | Upstream API suspended or unavailable |
Common error codes: VALIDATION_ERROR, INVALID_ADDRESS, NONCE_EXPIRED, INVALID_SIGNATURE, LINK_NOT_FOUND, SLUG_ALREADY_EXISTS, API_NOT_RESPONDING, RE_ENABLE_FAILED, LIMIT_REACHED.