Xenodia Docs
Capability Marketplace

Runtime API

Discover and invoke Xenodia marketplace capabilities from an authenticated agent or backend.

Capability runtime calls use the same base URL and authentication model as the rest of the Xenodia API.

export XENODIA_API_KEY="sk_xeno_..."
export XENODIA_BASE_URL="https://api.xenodia.xyz"

Authentication

Every /v1/capabilities/* endpoint requires:

Authorization: Bearer $XENODIA_API_KEY

If an agent wallet has not received a bearer token yet, the 401 recovery payload can point the agent to the wallet challenge and verify flow. Owner bootstrap should still happen through the normal owner login or API key flow.

List Capabilities

curl "$XENODIA_BASE_URL/v1/capabilities?mode=sync&q=intelligence" \
  -H "Authorization: Bearer $XENODIA_API_KEY"

Query parameters:

NameMeaning
qOptional case-insensitive search across slug, name, type, category, description, provider name, and tags.
modeOptional sync or async filter.

Response shape:

{
  "object": "list",
  "count": 1,
  "data": [
    {
      "slug": "unicatcher-query",
      "name": "UniCatcher",
      "type": "api",
      "category": "intelligence",
      "short_description": "High-quality intelligence retrieval...",
      "provider_name": "UniCatcher Agent Intelligence Gateway",
      "status": "active",
      "visibility": "consumer_listed",
      "default_version": "v1",
      "tags": ["info"],
      "supports_sync": true,
      "supports_async": false,
      "funding_modes": ["owner_only", "self_only", "self_then_owner"],
      "invoke_path": "/v1/capabilities/unicatcher-query/invoke",
      "agent_doc_what": "Use UniCatcher when...",
      "agent_doc_how": "For the 24-hour hot tweets use case...",
      "default_operation_slug": "query",
      "operations": [
        {
          "slug": "status",
          "name": "Status",
          "method": "GET",
          "path": "/v1/capabilities/unicatcher-query/operations/status",
          "read_only": true,
          "flow_step": 1,
          "pricing": {
            "billing_kind": "credit",
            "mode": "fixed",
            "unit_price_micro_usdc": 0,
            "currency": "USDC"
          },
          "supports_sync": true
        },
        {
          "slug": "monitors",
          "name": "List Monitors",
          "method": "GET",
          "path": "/v1/capabilities/unicatcher-query/operations/monitors",
          "read_only": true,
          "flow_step": 2,
          "pricing": {
            "billing_kind": "credit",
            "mode": "fixed",
            "unit_price_micro_usdc": 0,
            "currency": "USDC"
          },
          "supports_sync": true
        },
        {
          "slug": "query",
          "name": "Query Intelligence",
          "method": "POST",
          "path": "/v1/capabilities/unicatcher-query/invoke",
          "read_only": true,
          "flow_step": 3,
          "pricing": {
            "billing_kind": "credit",
            "mode": "fixed",
            "unit_price_micro_usdc": 10000,
            "currency": "USDC"
          },
          "idempotency_key_required": true,
          "supports_sync": true
        }
      ],
      "availability": {
        "effective_status": "active",
        "retryable": false,
        "list_visible": true,
        "detail_visible": true,
        "invoke_allowed": true
      }
    }
  ]
}

When a capability has multiple operations, root-level pricing can be omitted from list responses. Read each operation's pricing before invoking.

Get Capability Detail

curl "$XENODIA_BASE_URL/v1/capabilities/unicatcher-query" \
  -H "Authorization: Bearer $XENODIA_API_KEY"

The detail endpoint returns the descriptor in a wrapper:

{
  "object": "capability",
  "data": {
    "slug": "unicatcher-query",
    "operations": []
  }
}

Invoke responses are returned directly, not inside the descriptor wrapper.

Descriptor fields agents should inspect:

FieldUse
slugStable capability identifier used in routes and logs.
default_versionPublished contract version for the current runtime behavior.
supports_sync, supports_asyncWhether sync invoke, async task invoke, or both are available.
funding_modesBilling relationships allowed for this capability.
agent_doc_whatWhen to choose the capability.
agent_doc_howSafe operation sequence and special handling.
operationsOperation contracts, input fields, examples, prices, trust signals, and availability.
availability.invoke_allowedWhether an invoke can currently proceed.
health_summaryRuntime health signal when provider health checks are configured.

Invoke The Default Operation

curl "$XENODIA_BASE_URL/v1/capabilities/unicatcher-query/invoke" \
  -H "Authorization: Bearer $XENODIA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: unicatcher-query-2026-05-04T10-00-00Z" \
  -d '{
    "query": "Find recent high-signal developments",
    "filters": {
      "sourceTypes": ["twitter", "reddit"],
      "screeningStatus": ["qualified", "review"],
      "timeRangeHours": 24,
      "limit": 20,
      "sort": "publishedAt:desc"
    },
    "responseMode": "evidence_only"
  }'

You may also use an envelope when a capability supports multiple execution modes:

{
  "mode": "sync",
  "input": {
    "query": "Find recent high-signal developments"
  }
}

When the envelope form is used, only mode and input are allowed at the top level.

Invoke A Named Operation

Read-style operations may use GET with query parameters:

curl "$XENODIA_BASE_URL/v1/capabilities/unicatcher-query/operations/monitors?status=active&platform=twitter&limit=20" \
  -H "Authorization: Bearer $XENODIA_API_KEY"

Operations may also use POST with JSON:

curl "$XENODIA_BASE_URL/v1/capabilities/unicatcher-query/operations/query" \
  -H "Authorization: Bearer $XENODIA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: unicatcher-query-2026-05-04T10-05-00Z" \
  -d '{
    "query": "What happened around the monitored topic in the last 24 hours?",
    "responseMode": "evidence_only"
  }'

Success Response

Synchronous capability responses use:

{
  "success": true,
  "request_id": "capability-request-id",
  "capability": "unicatcher-query",
  "operation": "query",
  "capability_version": "v1",
  "mode": "sync",
  "billing": {
    "billing_session_id": 987,
    "billing_mode": "self_then_owner",
    "billing_scope": "self",
    "status": "committed",
    "unit_price_micro_usdc": 10000,
    "reserve_amount_micro_usdc": 10000,
    "actual_amount_micro_usdc": 10000,
    "released_amount_micro_usdc": 0,
    "actor": {
      "account_id": 123,
      "account_type": "agent"
    },
    "payer": {
      "account_id": 45,
      "account_type": "owner"
    }
  },
  "data": {}
}

Async capability responses return task instead of data and should be polled through the normal task resource.

Idempotency

Send Idempotency-Key for:

  • Any operation with idempotency_key_required: true.
  • Any paid operation.
  • Any async operation.

Reusing the same key with the same payload can replay the stored result. Reusing the same key with a different payload returns 409 idempotency_conflict.

Billing And 402

If the selected billing account has insufficient credit, the endpoint returns 402 insufficient_balance with payment headers and a payment object. The object includes topup_endpoint, required_amount_micro, currency, payment_kind, and capability context. Top up, then retry the same invoke with the same Idempotency-Key.

Common Errors

StatusErrorMeaning
400missing_idempotency_keyPaid, async, or policy-protected invoke was sent without an Idempotency-Key.
400capability_mode_unsupportedRequested mode is not supported by that operation.
401unauthorizedBearer token or API key is missing or invalid.
402insufficient_balanceBilling account needs credit before the invoke can continue.
404not_foundCapability or operation is not visible to the authenticated account.
409idempotency_conflictThe same idempotency key was reused with a different payload.
409request_in_progressA matching idempotent request is still running.
429capability_invoke_failedUpstream rate limit or request limit was reached.
502capability_invoke_failedUpstream HTTP, contract, or gateway execution failed.
503capability_unavailableRuntime, contract, or health state blocks new traffic; check reason and retryable.
504capability_invoke_failedUpstream transport timed out.

On this page