LaunaDocs
PLATFORM

API discovery

OpenAPI and x402 well-known manifests on gateway hosts

Paid APIs on launa gateways publish discovery documents automatically. Agents and indexes fetch them from the gateway hostname — not the seller API.

Gateway routes (public, unpaid)

RouteFormat
GET https://{api-host}/openapi.jsonOpenAPI 3.1 + x-payment-info
GET https://{api-host}/.well-known/x402.jsonOrigin manifest (x402 #2582)

{api-host} is the platform subdomain ({slug}.{platform_domain}) or any verified custom domain. Documents regenerate on each request from live endpoint config.

Ephemeral (TTL) and disabled endpoints are excluded.

Validate

Fetch the returned public discovery URLs and compare methods, paths, schemas, and payment terms with your configured API. No external checker is required.

launa discovery urls --api-id API_ID --json

Use launa_discovery_urls for the same discovery URLs through MCP.

API fields

API (POST /apis, PUT /apis/{id})

FieldTypeNotes
discovery_guidancestring?Maps to OpenAPI info.x-guidance
discovery_contact_emailstring?Overrides info.contact.email
openapi_versionstring?OpenAPI info.version (default 1.0.0)

Contact email resolution: API override → verified owner email → omit.

Endpoint (POST/PUT .../endpoints)

FieldTypeNotes
request_schemaobject?JSON Schema for request body
response_schemaobject?JSON Schema for 200 response
schema_sourcestring?Read-only: openapi | inferred | manual
clear_schemasbool?On update: clear and re-infer
ttlnumber?Lifetime in seconds (create only). Endpoint removed after first settle or expiry.
expires_atstring?Read-only ISO timestamp when ttl was set

Write semantics:

  • Create without schemas → infer minimal schemas (schema_source: inferred)
  • OpenAPI import → extract schemas when present (openapi)
  • Update with schemas → manual
  • clear_schemas: true → re-infer

Set or import a response_schema so agents can read output shape on 402 probes.

Ephemeral endpoints

Set ttl (seconds) when creating an endpoint to make it temporary. The control plane returns expires_at and removes the endpoint after the first successful payment or when the timer elapses. Ephemeral endpoints are excluded from gateway openapi.json and .well-known/x402.json discovery output.

Dashboard: API detail → Endpoints → Lifetime → Temporary.

launa endpoints create --api-id API_ID --path "/pay/{id}" --price-usdc 1.00 --ttl 3600 --json
await client.endpoints.create(apiId, {
  method: "GET",
  path_pattern: "/pay/*",
  accepts: [/* ... */],
  ttl: 3600,
});

GET /apis/{id}/discovery

{
  "primary_host": "myapi.example.com",
  "hosts": ["myapi.example.com", "api.mycompany.com"],
  "openapi_url": "https://myapi.example.com/openapi.json",
  "well_known_url": "https://myapi.example.com/.well-known/x402.json",
  "endpoint_count": 12,
  "discoverable_endpoint_count": 10,
  "host_urls": [
    {
      "host": "myapi.example.com",
      "openapi_url": "https://myapi.example.com/openapi.json",
      "well_known_url": "https://myapi.example.com/.well-known/x402.json",
      "is_primary": true
    }
  ]
}

Auth: apis:read.

SDK

Discovery fields are accepted on create and update.

TypeScript

await client.apis.create({
  name: "Search",
  slug: "search",
  upstream_base_url: "https://upstream.example.com",
  discovery_guidance: "Use POST /search with a query field.",
  discovery_contact_email: "support@example.com",
  openapi_version: "1.0.0",
});
const urls = await client.apis.discovery(apiId);
await client.endpoints.update(apiId, endpointId, {
  request_schema: { type: "object", properties: { query: { type: "string" } }, required: ["query"] },
  response_schema: { type: "object", additionalProperties: true },
});

Go

api, err := client.CreateAPI(ctx, launa.CreateAPIInput{
  Name: "Search", Slug: "search", UpstreamBaseURL: "https://upstream.example.com",
  DiscoveryGuidance: "Use POST /search with a query field.",
  DiscoveryContactEmail: "support@example.com",
})
disc, err := client.GetAPIDiscovery(ctx, api.ID)

Python

api = client.apis.create({
  "name": "Search",
  "slug": "search",
  "upstream_base_url": "https://upstream.example.com",
  "discovery_guidance": "Use POST /search with a query field.",
  "discovery_contact_email": "support@example.com",
})
urls = client.apis.discovery(api.id)

Language guides: TypeScript · Go · Python

CLI

launa apis create --name Search --slug search --upstream https://upstream.example.com \
  --discovery-guidance "Use POST /search." --discovery-contact-email support@example.com

launa apis discovery --id API_ID --json
launa discovery urls --api-id API_ID --json

launa endpoints update --api-id API_ID --endpoint-id EP \
  --request-schema '{"type":"object","properties":{"query":{"type":"string"}}}' \
  --response-schema '{"type":"object","additionalProperties":true}'

Full command list: CLI reference

MCP

ToolPurpose
launa_discovery_urlsGET /apis/{id}/discovery
launa_set_discovery_guidanceSet guidance / contact / OpenAPI version
launa_update_endpoint_schemasSet or clear endpoint JSON Schemas
launa_create_apiCreate API; optional discovery fields on create
launa_import_openapiImport ops; schemas persisted when present

Full tool list: MCP server

On this page