Developers
API Reference

API Reference

Complete reference for the 1ly API. All authenticated endpoints require an API key.

Base URL

https://1ly.store

Authentication

All authenticated endpoints require an API key in the Authorization header:

Authorization: Bearer 1ly_your_api_key_here

How to Get Your API Key

There are 3 ways to obtain an API key:

Option 1: Via Dashboard (Manual)

  1. Create an account at 1ly.store/login (opens in a new tab)
  2. Go to Settings → Developer
  3. Enable Developer Mode
  4. Click Create API Key

Option 2: Programmatic (Wallet-based)

  1. Use the agent signup flow below (no email required)
  2. Get an API key instantly via wallet signature
  3. Best for AI agents and automated systems

Option 3: Via MCP Server

  1. Install and run the 1ly MCP server
  2. Run 1ly_create_store to generate a store + API key automatically
  3. 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/nonce

Body:

{
  "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/signup

Body:

{
  "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/:username

No 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"
}
FieldTypeRequiredDescription
urlstringYesThe backend URL to proxy requests to
titlestringYesDisplay name (max 200 chars)
descriptionstringNoShort description (max 500 chars)
slugstringNoURL slug (auto-generated if omitted)
pricestringNoPrice in USDC, e.g. "0.10" (default: "0")
isPublicbooleanNoShow in marketplace (default: false)
isStealthbooleanNoPrivate link with secret URL
webhookUrlstringNoWebhook 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/discover

No authentication required.

Query Parameters:

ParamDescription
qSearch query
typeapi or standard
minPriceMinimum price
maxPriceMaximum price
sortpopular (default), newest, price_asc, price_desc
limitMax results (default: 20, max: 100)
offsetPagination 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/:slug

Returns 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:

StatusCodeMeaning
402payment_requiredNo payment header sent
400invalid_paymentBad transaction
503api_suspendedSeller's API is unhealthy
502upstream_errorSeller's backend returned 5xx

Note: Building blockchain transactions manually is complex. Use the 1ly MCP server which does this automatically via the 1ly_call tool.

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:

ParamValuesDefault
period7d, 30d, 90d, all30d
linkIdUUID 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:

WindowLimit
Per minute100 requests
Per hour1,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 window
  • X-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"
  }
}
StatusMeaning
400Bad request / validation error
401Missing or invalid API key
402Payment required
403Forbidden
404Not found
409Conflict (e.g. slug already taken)
422Unprocessable entity
500Server error
503Upstream 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.