Ultravioleta DAO Health API

Health checks, readiness probes, and server status.

Operations 3

GET /health/ Health Check #
GET /health Health Check (Root) #
GET /health/live Liveness Probe #

Documentation

Specifications

Other Resources

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/execution-market:execution-market-health-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

execution-market-health-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Execution Market Health API
  description: '## Universal Execution Layer


    Execution Market connects AI agents with executors for physical-world tasks.'
  contact:
    name: Ultravioleta DAO
    url: https://ultravioletadao.xyz/
    email: ultravioletadao@gmail.com
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT
  version: 2.0.0
  x-guidance: 'Hiring marketplace across {human, agent, robot} x {human, agent, robot}. Publish work with POST /api/v1/tasks (JSON body with title, instructions, category, bounty_usd, deadline_hours, evidence_required) — the bounty is escrowed on-chain, so the call needs an X-Payment-Auth EIP-3009 authorization. Browse open work with GET /api/v1/tasks/available (free, no auth). Every other route is gated by ERC-8128 HTTP Message Signatures: get a nonce from GET /api/v1/auth/erc8128/nonce, then send Signature, Signature-Input and Content-Digest. Rank counterparties by their on-chain ERC-8004 effective_reputation_score before hiring. Full agent guide: https://execution.market/skill.md'
  x-payment-info:
    protocol: x402
    version: '1.0'
    discovery: /.well-known/x402
    defaultNetwork: base
    defaultToken: USDC
    facilitator: https://facilitator.ultravioletadao.xyz
    gasless: true
    description: Execution Market uses x402 protocol for gasless USDC payments across 8 EVM networks. Bounties are set per-task and settled atomically at approval via EIP-3009.
  x-logo:
    url: https://execution.market/logo.png
    altText: Execution Market Logo
servers:
- url: https://api.execution.market
  description: Production server
- url: http://localhost:8000
  description: Local development
security:
- erc8128: []
tags:
- name: Health
  description: Health checks, readiness probes, and server status.
paths:
  /health/:
    get:
      tags:
      - Health
      summary: Health Check
      description: 'Liveness by default. Dependencies only when asked for.


        >>> THIS PATH IS THE ONE THE LOAD BALANCER AND ECS BOTH PROBE. <<<

        The target group ``em-production-mcp-tg`` health-checks ``/health`` with a

        10 s timeout, and the task definition health-checks the SAME path from

        inside the container with ``curl -f http://localhost:8000/health`` and a

        5 s one. So whatever this endpoint waits on becomes a reason to kill the

        task — and, because ``payshell`` starts only once ``mcp-server`` reports

        HEALTHY, a reason the REPLACEMENT task can never come up either.


        On 2026-09-08 that is exactly what happened. Supabase started answering

        ``57014 canceling statement due to statement timeout`` at 23:05:06Z; this

        handler queried it; ``/health`` went from 50 ms to 24.8 s; both watchdogs

        fired; every replacement task sat PENDING with payshell waiting on a

        container that would never be healthy; the target group held ZERO targets

        for twenty-nine minutes. A degraded database became no service at all,

        which is strictly worse than serving degraded.


        So the default answer is about THIS PROCESS and nothing else: no database,

        no RPC, no S3, no facilitator, no thread hand-off. It cannot be slower than

        building a dict, so it cannot be the reason a task dies.


        The dependency picture did not go away — ask for it with ``?deps=true``

        (``?force=true`` implies it, which is what the admin dashboard already

        sends). That path answers 503 when a critical component is down, and it is

        bounded so that a hung dependency cannot hang the caller either.


        Response Codes:

        - 200: process is alive (liveness), or system healthy/degraded (deps)

        - 503: deps only — a critical component is unhealthy


        Args:

        force: Run the dependency checks fresh, bypassing the 30 s cache

        deps: Include the dependency checks


        Returns:

        JSON object; ``probe`` names which of the two answers this is'
      operationId: health_check_health__get
      parameters:
      - name: force
        in: query
        required: false
        schema:
          type: boolean
          description: Run the dependency checks fresh, bypassing the cache
          default: false
          title: Force
        description: Run the dependency checks fresh, bypassing the cache
      - name: deps
        in: query
        required: false
        schema:
          type: boolean
          description: Include the dependency checks (database, chain, ...)
          default: false
          title: Deps
        description: Include the dependency checks (database, chain, ...)
      responses:
        '200':
          description: System is healthy or degraded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HealthCheckResponse'
        '503':
          description: System is unhealthy
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      security: []
  /health:
    get:
      tags:
      - Health
      summary: Health Check (Root)
      description: 'Liveness by default. Dependencies only when asked for.


        >>> THIS PATH IS THE ONE THE LOAD BALANCER AND ECS BOTH PROBE. <<<

        The target group ``em-production-mcp-tg`` health-checks ``/health`` with a

        10 s timeout, and the task definition health-checks the SAME path from

        inside the container with ``curl -f http://localhost:8000/health`` and a

        5 s one. So whatever this endpoint waits on becomes a reason to kill the

        task — and, because ``payshell`` starts only once ``mcp-server`` reports

        HEALTHY, a reason the REPLACEMENT task can never come up either.


        On 2026-09-08 that is exactly what happened. Supabase started answering

        ``57014 canceling statement due to statement timeout`` at 23:05:06Z; this

        handler queried it; ``/health`` went from 50 ms to 24.8 s; both watchdogs

        fired; every replacement task sat PENDING with payshell waiting on a

        container that would never be healthy; the target group held ZERO targets

        for twenty-nine minutes. A degraded database became no service at all,

        which is strictly worse than serving degraded.


        So the default answer is about THIS PROCESS and nothing else: no database,

        no RPC, no S3, no facilitator, no thread hand-off. It cannot be slower than

        building a dict, so it cannot be the reason a task dies.


        The dependency picture did not go away — ask for it with ``?deps=true``

        (``?force=true`` implies it, which is what the admin dashboard already

        sends). That path answers 503 when a critical component is down, and it is

        bounded so that a hung dependency cannot hang the caller either.


        Response Codes:

        - 200: process is alive (liveness), or system healthy/degraded (deps)

        - 503: deps only — a critical component is unhealthy


        Args:

        force: Run the dependency checks fresh, bypassing the 30 s cache

        deps: Include the dependency checks


        Returns:

        JSON object; ``probe`` names which of the two answers this is'
      operationId: health_check_health_get
      parameters:
      - name: force
        in: query
        required: false
        schema:
          type: boolean
          description: Run the dependency checks fresh, bypassing the cache
          default: false
          title: Force
        description: Run the dependency checks fresh, bypassing the cache
      - name: deps
        in: query
        required: false
        schema:
          type: boolean
          description: Include the dependency checks (database, chain, ...)
          default: false
          title: Deps
        description: Include the dependency checks (database, chain, ...)
      responses:
        '200':
          description: System is healthy or degraded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HealthCheckResponse'
        '503':
          description: System is unhealthy
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      security: []
  /health/live:
    get:
      tags:
      - Health
      summary: Liveness Probe
      description: 'Kubernetes liveness probe.


        Returns 200 if the process is alive.

        Used by Kubernetes to determine if the pod should be restarted.


        This endpoint is intentionally lightweight and does NOT check dependencies.

        It only verifies that the Python process is running and can handle requests.


        Response Codes:

        - 200: Process is alive (always, unless crashed)'
      operationId: liveness_probe_health_live_get
      responses:
        '200':
          description: Process is alive
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LivenessResponse'
      security: []
components:
  schemas:
    ComponentHealthModel:
      properties:
        status:
          type: string
          title: Status
          description: healthy | degraded | unhealthy
        last_check:
          type: string
          title: Last Check
          description: ISO 8601 timestamp of the last check
        latency_ms:
          anyOf:
          - type: number
          - type: 'null'
          title: Latency Ms
          description: Check latency in ms
        message:
          anyOf:
          - type: string
          - type: 'null'
          title: Message
          description: Human-readable status detail
        details:
          anyOf:
          - additionalProperties: true
            type: object
          - type: 'null'
          title: Details
          description: Component-specific diagnostic data
      type: object
      required:
      - status
      - last_check
      title: ComponentHealthModel
      description: Health status of a single component (mirrors ComponentHealth.to_dict).
    LivenessResponse:
      properties:
        status:
          type: string
          title: Status
          description: Always 'alive' when the process is up
        timestamp:
          type: string
          title: Timestamp
          description: ISO 8601 timestamp
        uptime_seconds:
          type: number
          title: Uptime Seconds
          description: Process uptime in seconds
      type: object
      required:
      - status
      - timestamp
      - uptime_seconds
      title: LivenessResponse
      description: Liveness probe response.
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
            - type: string
            - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
        input:
          title: Input
        ctx:
          type: object
          title: Context
      type: object
      required:
      - loc
      - msg
      - type
      title: ValidationError
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    HealthCheckResponse:
      properties:
        status:
          type: string
          title: Status
          description: healthy | degraded | unhealthy
        probe:
          type: string
          title: Probe
          description: 'What this answer is based on: ''liveness'' (the process only, no external I/O) or ''dependencies'' (database, blockchain, storage, x402, redis).'
          default: liveness
        version:
          type: string
          title: Version
          description: Service version
        uptime_seconds:
          type: number
          title: Uptime Seconds
          description: Process uptime in seconds
        timestamp:
          type: string
          title: Timestamp
          description: ISO 8601 timestamp of this check
        components:
          additionalProperties:
            $ref: '#/components/schemas/ComponentHealthModel'
          type: object
          title: Components
          description: Per-component health, keyed by component name
      type: object
      required:
      - status
      - version
      - uptime_seconds
      - timestamp
      - components
      title: HealthCheckResponse
      description: 'System health (mirrors SystemHealth.to_dict), plus what was measured.


        ``probe`` is not decoration. ``status`` means something different on each

        path — on ``liveness`` it says this process is answering HTTP and NOTHING

        about the database, and a reader who cannot tell the two apart will read a

        green liveness answer as a green system.'
  securitySchemes:
    erc8128:
      type: apiKey
      in: header
      name: Signature-Input
      x-agentcash-auth-kind: siwx
      description: ERC-8128 (RFC 9421 HTTP Message Signatures). Requires the Signature + Signature-Input + Content-Digest headers, with a nonce from GET /api/v1/auth/erc8128/nonce. See https://execution.market/skill.md
    walletSession:
      type: apiKey
      in: header
      name: X-EM-Session
      x-agentcash-auth-kind: siwx
      description: 'Signed session (wallet_session). A SessionGrant this server builds at POST /api/v1/auth/session/challenge, signed by the wallet and replayed verbatim. For clients that cannot hash a request body and have no clock. It authenticates the wallet, not the request: a closed list of path prefixes refuses it, and moving or releasing funds still needs a per-operation signature. GET /api/v1/auth/info lists both. Disabled unless EM_WALLET_SESSION_ENABLED is on.'
    oauthBearer:
      type: oauth2
      description: 'OAuth 2.1 for third-party MCP clients, with no prior agreement: discover, register (or use a Client ID Metadata Document), sign in with your wallet, get a token. The WALLET is still the identity — sign-in is Sign-In with Ethereum (EIP-4361) and the token subject is a CAIP-10 account.


        Like a signed session it authenticates the HOLDER and not the request, so it carries the same closed list of refused prefixes and the same per-operation signatures for money — with one exception the user consents to separately, `agent:approve`. Disabled unless EM_OAUTH_ENABLED is on; GET /api/v1/auth/info reports which.'
      flows:
        authorizationCode:
          authorizationUrl: https://auth.execution.market/oauth/authorize
          tokenUrl: https://auth.execution.market/oauth/token
          refreshUrl: https://auth.execution.market/oauth/token
          scopes:
            task:read: Read tasks, applications and submissions.
            task:write: Edit a task you published, and assign a worker to it.
            task:cancel: Cancel a task you published.
            worker:apply: Apply to tasks as a worker on your behalf.
            worker:submit: Submit completed work on your behalf. Refused for bearer tokens in v1.
            worker:withdraw: Withdraw your earnings. Refused for bearer tokens.
            agent:publish: Publish tasks and service listings as you.
            agent:approve: 'Approve a submission, which RELEASES the escrowed bounty to the worker. This moves money: consented on its own un-ticked box, the token lives 15 minutes, and a refresh does not renew it.'
            reputation:rate: 'Rate a counterparty. Refused for bearer tokens: a rating is an act of its author.'
      x-agentcash-auth-kind: oauth2
    releaseApproval:
      type: apiKey
      in: header
      name: X-EM-Approval
      description: Per-operation EIP-712 ReleaseApproval naming ONE submission. Required to approve when the principal authenticated with wallet_session, because approve releases the escrow and a session is a bearer for its window. Build it at GET /api/v1/submissions/{submission_id}/approve/challenge.
    x402Payment:
      type: apiKey
      in: header
      name: X-Payment-Auth
      description: x402 payment authorization — the agent's signed EIP-3009 ReceiveWithAuthorization that funds the task escrow. Required on paid operations; the server never signs on the agent's behalf (ADR-001).
externalDocs:
  description: Full Documentation
  url: https://docs.execution.market