sarnai-dev Score API

The Score API from sarnai-dev — 1 operation(s) for score.

Operations 1

GET /score/{agent_id} Get Trust Score #

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/sarnai-dev:sarnai-dev-score-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

sarnai-dev-score-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Agent Output Verifier by SarnAI Score API
  description: 'Independent verification of AI agent output before you pay: check an AI agent''s JSON against your JSON Schema and business rules (totals, unique IDs). Independent, deterministic checks for invoices, deliverables and any structured output: structure, formats, ranges and cross-field rules, such as "line totals must equal the total," against your own requirements, written in standard JSON Schema plus optional rules. Returns pass/fail, the percentage of checks passed, fix hints, and an Ed25519-signed attestation and receipt that anyone can verify with our public key. Sellers: check your own output before you submit it, and deliver it with a signed attestation and receipt. No signup: pay per call with x402 v2, in USDC on Base or Solana. 1,000 free checks a day per caller, then $0.02 per check (x402, USDC on Base or Solana). AI Agent Scores: $0.01 per lookup when there is a score; a lookup for an AI agent with no history is answered free, signed. `POST /verify/schema` (also offered as `POST /verify/deliverable`: the same check, shape, signed attestation and receipt, price and networks) is $0.02 USDC per call and `GET /score/{agent_id}` is $0.01 USDC per call, both paid via x402 in USDC on Base or Solana (an unpaid request gets HTTP 402, which lists the options in the `Payment-Required` response header; a paid request''s signed payment rides in the `Payment-Signature` request header, and a settled response''s settlement receipt rides in the `Payment-Response` response header). A `fail` result is a complete, valid answer and is charged the same as a `pass`. **Payment errors:** every 402 body is a structured `payment_error` - a stable `error_code` (`no_payment`, `malformed_payment`, `unsupported_payment_version`, `no_matching_requirements`, `amount_mismatch`, `recipient_mismatch`, `invalid_signature`, `expired_authorization`, `payment_already_used`, `insufficient_funds`, `facilitator_unreachable`, `facilitator_error`), a clean `message`, `charged: false`, `retryable`/`retry_after`, the current `payment_terms`, and `next_actions` - identical on REST and in MCP''s `structuredContent.payment_error`. See the 402 response below for what each code means. **Free verification:** 1,000 free checks a day per caller, then $0.02 per check (x402, USDC on Base or Solana). One counter is shared by the MCP tool `verify_schema` (`POST /mcp`) and the REST routes `POST /verify/schema` and `POST /verify/deliverable`, where a valid unpaid request is served free and says what is left in the `Free-Allowance-Remaining`, `Free-Allowance-Limit` and `Free-Allowance-Resets` response headers. An unpaid request that needs payment gets a 402 whose body reports this caller''s own remaining free allowance. **AI Agent Scores:** `GET /score/{agent_id}` and the MCP tool `get_verification_record` are $0.01 per lookup when there is a score, with no free allowance; a lookup for an AI agent with no history (or a reserved `test-` id) is answered free, signed, with `reason: no_data`, on REST and through the MCP tool. **Errors:** every error other than a payment error has one shape (`code`, `message`, `status`, `retryable`, `charged`, `next_actions`; validation errors add a `fields` list naming each bad field and how to fix it), on REST and in MCP tool results, and the caller''s input is never echoed. An invalid request is rejected with 422 before anything is verified or settled; an unpaid request to a paid route always gets the 402 challenge, an empty or invalid one with `request_problems`, and GET/HEAD on the verify routes get the same challenge. Every error response (4xx and 5xx, every route) carries a `guidance` block: what to do, a minimal valid example, the price and how to pay, the free-allowance note and the llms.txt link; a 5xx also says nothing was charged and when to retry. The live free-allowance numbers are stated in one place, the "Free allowance" section of `/llms.txt`.'
  version: 0.5.8
tags:
- name: Score
paths:
  /score/{agent_id}:
    get:
      summary: Get Trust Score
      operationId: get_trust_score_score__agent_id__get
      parameters:
      - name: agent_id
        in: path
        required: true
        schema:
          type: string
          minLength: 1
          maxLength: 200
          pattern: ^[^\x00-\x1f\x7f]+$
          description: 'The agent_id whose verification history to score (as passed to /verify/schema): the AI agent that produced the output checked by those calls (for example, the seller). agent_ids starting with ''test-'' are reserved for testing and never have a history.'
          title: Agent Id
        description: 'The agent_id whose verification history to score (as passed to /verify/schema): the AI agent that produced the output checked by those calls (for example, the seller). agent_ids starting with ''test-'' are reserved for testing and never have a history.'
      - name: Payment-Signature
        in: header
        required: false
        schema:
          type: string
        description: The caller's signed x402 v2 payment (base64). Omit it to receive 402 with the price and requirements in the Payment-Required response header instead.
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TrustScoreResponse'
          headers:
            Payment-Response:
              description: Settlement receipt (base64 JSON) once a paid call settles on-chain.
              schema:
                type: string
        '422':
          description: 'Invalid request: bad JSON, a missing field, a wrong type, an unknown rule type, an over-long id, with a payment attached (an UNPAID invalid request gets the 402 challenge instead, with `request_problems`); `fields` names each bad field and how to fix it. Nothing is verified or charged, and the input is never echoed.'
          content:
            application/json:
              schema:
                type: object
                properties:
                  code:
                    type: string
                    enum:
                    - invalid_request
                    - invalid_json
                    - schema_invalid
                    - validation_timeout
                    - unencodable_content
                    - request_too_large
                    - invalid_content_type
                    - not_found
                    - method_not_allowed
                    - rate_limited
                    - too_many_concurrent_validations
                    - service_busy
                    - internal_error
                    - unknown_tool
                    description: '- `invalid_request`: A field is missing, has the wrong type, is outside its limits or holds a value outside the allowed set. `fields` lists each one with how to fix it.

                      - `invalid_json`: The body is malformed JSON, or is something other than a single JSON object.

                      - `schema_invalid`: `expected_schema` is an invalid JSON Schema.

                      - `validation_timeout`: The schema/output pair took too long to validate (too complex).

                      - `unencodable_content`: The request contains a lone (unpaired) Unicode surrogate, which the signature format rejects.

                      - `request_too_large`: The request body is over the size limit. `limits` gives it.

                      - `invalid_content_type`: The request''s Content-Type names a type other than JSON. Send the same JSON body with Content-Type: application/json.

                      - `not_found`: No such route.

                      - `method_not_allowed`: The route exists for other HTTP methods only. `limits.allowed_methods` lists them.

                      - `rate_limited`: Too many requests from this client (or a daily cap); retry after the `Retry-After` seconds.

                      - `too_many_concurrent_validations`: Too many validations already running for this client; retry shortly.

                      - `service_busy`: Every validation worker was busy; retry shortly.

                      - `internal_error`: The service failed while handling the request. Nothing was charged; retry after `retry_after` seconds.

                      - `unknown_tool`: MCP: no tool with that name. `limits.tools` lists the tools.'
                  message:
                    type: string
                    description: One sentence a person can act on. Never repeats the caller's input.
                  status:
                    type: integer
                    description: The HTTP status (also present in MCP tool errors).
                  retryable:
                    type: boolean
                    description: Whether sending the same request again can succeed.
                  retry_after:
                    type:
                    - integer
                    - 'null'
                    description: 'Present on a retryable error: seconds to wait, or null.'
                  charged:
                    type: boolean
                    description: 'Always false: an error is never charged.'
                  next_actions:
                    type: array
                    items:
                      type: object
                    description: Machine-readable next steps.
                  fields:
                    type: array
                    description: 'Validation errors (422): one entry per bad field, at most ten.'
                    items:
                      type: object
                      properties:
                        field:
                          type: string
                          description: 'Where, as a path: `rules[0].type`.'
                        problem:
                          type: string
                        fix:
                          type: string
                      required:
                      - field
                      - problem
                      - fix
                  fields_total:
                    type: integer
                    description: Present when more fields were bad than are listed.
                  limits:
                    type: object
                    description: The numbers that apply (a size limit, the allowed methods, the tool list).
                  detail:
                    description: 'Kept for older clients: FastAPI''s former `detail` (never the caller''s input).'
                required:
                - code
                - message
                - status
                - retryable
                - charged
                - next_actions
        '402':
          description: 'Payment required (x402 v2) - see the Payment-Required response header for the price and requirements. The body is always a structured `payment_error` (stable `error_code`, a clean `message`, `charged: false`, `retryable`/`retry_after`, `payment_terms`, and `next_actions`), the same shape MCP returns in `structuredContent.payment_error`, merged with a `free_trial` note when the free trial is on.'
          headers:
            Payment-Required:
              description: 'x402 v2 payment requirements (base64 JSON): price, network(s) and pay-to address.'
              schema:
                type: string
          content:
            application/json:
              schema:
                type: object
                properties:
                  payment_error:
                    type: object
                    properties:
                      error_code:
                        type: string
                        enum:
                        - no_payment
                        - malformed_payment
                        - unsupported_payment_version
                        - no_matching_requirements
                        - amount_mismatch
                        - recipient_mismatch
                        - invalid_signature
                        - expired_authorization
                        - payment_already_used
                        - insufficient_funds
                        - facilitator_unreachable
                        - facilitator_error
                        description: '- `no_payment`: No payment was attached to the request.

                          - `malformed_payment`: The payment is unreadable as an x402 v2 payment: its header is invalid base64 or JSON (REST), its `x402/payment` meta is anything other than a JSON object (MCP), `x402Version` is absent, or a required member (`accepted` with its scheme, network, asset, amount, payTo and maxTimeoutSeconds; `payload`) is absent or has the wrong type. A payment the facilitator reports as unreadable is classed the same way. The message names the member, never its value.

                          - `unsupported_payment_version`: The payment declares an x402 version other than 2 (for example 1); only v2 is accepted. A v2 payment that is merely incomplete is malformed_payment instead.

                          - `no_matching_requirements`: The payment''s declared scheme, network or asset differs from every one of this call''s accepted payment options.

                          - `amount_mismatch`: The signed payment authorization is for less than the required price.

                          - `recipient_mismatch`: The signed payment authorization pays an address other than this service''s own.

                          - `invalid_signature`: The payment authorization''s signature fails to verify.

                          - `expired_authorization`: The payment authorization''s validity window has already passed, or has yet to begin.

                          - `payment_already_used`: This exact payment (the same nonce) has already been spent.

                          - `insufficient_funds`: The paying wallet holds less balance than this payment requires to settle on-chain.

                          - `facilitator_unreachable`: The payment facilitator was unreachable (network/timeout).

                          - `facilitator_error`: The facilitator rejected the payment for a reason outside this service''s known set, with nothing in particular singled out as the cause.'
                      message:
                        type: string
                        description: A clean, human-readable sentence - never a raw exception or facilitator JSON.
                      charged:
                        type: boolean
                        description: 'Always false: none of these codes represent a settled payment.'
                      retryable:
                        type: boolean
                        description: Whether resubmitting (the same payment, or a corrected one) can succeed.
                      retry_after:
                        type:
                        - integer
                        - 'null'
                        description: Seconds to wait before retrying, when retryable and the failure is transient (facilitator-side).
                      payment_terms:
                        type: object
                        description: The same accepts[]/resource a fresh unpaid request to this route would receive.
                      next_actions:
                        type: array
                        items:
                          type: object
                        description: Machine-readable next step(s), same pattern as a verification result's next_actions.
                      free_trial_status:
                        type: string
                        description: One-line free-trial status, present only when relevant.
                    required:
                    - error_code
                    - message
                    - charged
                    - retryable
                    - retry_after
                    - payment_terms
                    - next_actions
                  free_trial:
                    type: object
                    description: Present when the free trial is on - see GET /llms.txt's Free trial section.
                required:
                - payment_error
        '429':
          description: Too many requests, or too many validations running for this client; see `retry_after`.
          content:
            application/json:
              schema:
                type: object
                properties:
                  code:
                    type: string
                    enum:
                    - invalid_request
                    - invalid_json
                    - schema_invalid
                    - validation_timeout
                    - unencodable_content
                    - request_too_large
                    - invalid_content_type
                    - not_found
                    - method_not_allowed
                    - rate_limited
                    - too_many_concurrent_validations
                    - service_busy
                    - internal_error
                    - unknown_tool
                    description: '- `invalid_request`: A field is missing, has the wrong type, is outside its limits or holds a value outside the allowed set. `fields` lists each one with how to fix it.

                      - `invalid_json`: The body is malformed JSON, or is something other than a single JSON object.

                      - `schema_invalid`: `expected_schema` is an invalid JSON Schema.

                      - `validation_timeout`: The schema/output pair took too long to validate (too complex).

                      - `unencodable_content`: The request contains a lone (unpaired) Unicode surrogate, which the signature format rejects.

                      - `request_too_large`: The request body is over the size limit. `limits` gives it.

                      - `invalid_content_type`: The request''s Content-Type names a type other than JSON. Send the same JSON body with Content-Type: application/json.

                      - `not_found`: No such route.

                      - `method_not_allowed`: The route exists for other HTTP methods only. `limits.allowed_methods` lists them.

                      - `rate_limited`: Too many requests from this client (or a daily cap); retry after the `Retry-After` seconds.

                      - `too_many_concurrent_validations`: Too many validations already running for this client; retry shortly.

                      - `service_busy`: Every validation worker was busy; retry shortly.

                      - `internal_error`: The service failed while handling the request. Nothing was charged; retry after `retry_after` seconds.

                      - `unknown_tool`: MCP: no tool with that name. `limits.tools` lists the tools.'
                  message:
                    type: string
                    description: One sentence a person can act on. Never repeats the caller's input.
                  status:
                    type: integer
                    description: The HTTP status (also present in MCP tool errors).
                  retryable:
                    type: boolean
                    description: Whether sending the same request again can succeed.
                  retry_after:
                    type:
                    - integer
                    - 'null'
                    description: 'Present on a retryable error: seconds to wait, or null.'
                  charged:
                    type: boolean
                    description: 'Always false: an error is never charged.'
                  next_actions:
                    type: array
                    items:
                      type: object
                    description: Machine-readable next steps.
                  fields:
                    type: array
                    description: 'Validation errors (422): one entry per bad field, at most ten.'
                    items:
                      type: object
                      properties:
                        field:
                          type: string
                          description: 'Where, as a path: `rules[0].type`.'
                        problem:
                          type: string
                        fix:
                          type: string
                      required:
                      - field
                      - problem
                      - fix
                  fields_total:
                    type: integer
                    description: Present when more fields were bad than are listed.
                  limits:
                    type: object
                    description: The numbers that apply (a size limit, the allowed methods, the tool list).
                  detail:
                    description: 'Kept for older clients: FastAPI''s former `detail` (never the caller''s input).'
                required:
                - code
                - message
                - status
                - retryable
                - charged
                - next_actions
      tags:
      - Score
components:
  schemas:
    VerifySection:
      properties:
        public_key_url:
          type: string
          title: Public Key Url
          description: Agent-card URL listing the public key for key_version below, and every key this service has ever signed with.
        key_version:
          type: string
          title: Key Version
          description: Matches attestation.key_version.
        canonicalization:
          type: string
          title: Canonicalization
          description: How every hash below, and the signed bytes themselves, are computed.
        hash_algorithm:
          type: string
          title: Hash Algorithm
          description: Algorithm behind every *_hash field in this response.
        service:
          type: string
          title: Service
          description: This service's name.
        mcp:
          type: string
          title: Mcp
          description: This service's MCP (Model Context Protocol) endpoint.
      type: object
      required:
      - public_key_url
      - key_version
      - canonicalization
      - hash_algorithm
      - service
      - mcp
      title: VerifySection
      description: 'Compact, self-describing block every signed attestation and receipt carries (2026-09-30,

        verifier_version 0.4.0) - inside the signature, alongside `attestation` itself - so a

        verifier needs nothing but this response and the URL below, not a separate lookup or

        prior knowledge of this service''s conventions.'
    ScoreFactor:
      properties:
        name:
          type: string
          title: Name
          description: Stable identifier of this factor.
        value:
          anyOf:
          - type: number
          - type: 'null'
          title: Value
          description: Factor value in [0, 1]; null when it cannot be computed (see the response's `reason`).
        confidence_interval_95:
          anyOf:
          - items:
              type: number
            type: array
            maxItems: 2
            minItems: 2
          - type: 'null'
          title: Confidence Interval 95
          description: '[lower, upper] 95% Wilson score interval; null when value is null.'
        sample_size:
          type: integer
          title: Sample Size
          description: Raw number of verification calls behind this factor, all history.
        effective_sample_size:
          type: number
          title: Effective Sample Size
          description: 'Sum of the recency weights: how many ''recent-equivalent'' observations the history is worth. This, not sample_size, is what the interval is computed from.'
        parameters:
          additionalProperties:
            anyOf:
            - type: number
            - type: integer
            - type: string
          type: object
          title: Parameters
          description: Parameters in force, so the value can be reproduced.
      type: object
      required:
      - name
      - value
      - confidence_interval_95
      - sample_size
      - effective_sample_size
      - parameters
      title: ScoreFactor
      description: One input to the score. v1 has exactly one; later versions add entries here.
    TrustScoreResponse:
      properties:
        agent_id:
          type: string
          title: Agent Id
          description: 'Identifies the AI agent that produced the output checked by the /verify/schema calls this score is built from (for example, the seller): this record belongs to that producer.'
        identity_verified:
          type: boolean
          title: Identity Verified
          description: 'Whether agent_id is bound to a proven identity. Currently always false: agent_id is an unauthenticated label chosen by whoever called /verify/schema, so this history may include calls made by anyone under that id, and the score says nothing about who the AI agent really is. It flips to true only if and when identity is actually authenticated.'
        trust_score:
          anyOf:
          - type: number
          - type: 'null'
          title: Trust Score
          description: Recency-weighted pass rate as a raw float in [0.0, 1.0]; null when there is nothing meaningful to report (see `reason`). A statistical summary of structural verification history, not a measure of overall trustworthiness and not a prediction of future behavior.
        sample_size:
          type: integer
          title: Sample Size
          description: Total verification calls on record for this agent_id.
        confidence_interval_95:
          anyOf:
          - items:
              type: number
            type: array
            maxItems: 2
            minItems: 2
          - type: 'null'
          title: Confidence Interval 95
          description: '[lower, upper] 95% Wilson score interval around trust_score, computed from the effective (recency-discounted) sample size. Wide = little recent evidence.'
        basis:
          type: string
          title: Basis
          description: Names the formula behind trust_score. Its meaning never changes under the same name; a different formula gets a different basis.
        reason:
          anyOf:
          - type: string
          - type: 'null'
          title: Reason
          description: 'null when scored. ''no_data'': no verification history at all. ''insufficient_recent_data'': history exists but has decayed to under 0.05 effective observations.'
        factors:
          items:
            $ref: '#/components/schemas/ScoreFactor'
          type: array
          title: Factors
          description: The inputs behind trust_score. v1 has one entry; consumers should ignore entries they don't recognize, so factors can be added without breaking them.
        verified_count:
          type: integer
          title: Verified Count
          description: Raw number of /verify/schema calls on record for this agent_id (all history, no recency weighting). Equals sample_size.
        passed_count:
          type: integer
          title: Passed Count
          description: How many of those calls returned result 'pass'.
        failed_count:
          type: integer
          title: Failed Count
          description: How many of those calls returned result 'fail'.
        last_seen:
          anyOf:
          - type: string
          - type: 'null'
          title: Last Seen
          description: ISO-8601 UTC time of the most recent verification on record; null when there is none. Like agent_id itself, this reflects calls made under this label by anyone.
        computed_at:
          type: string
          title: Computed At
          description: ISO-8601 UTC time the score was computed; ages are measured from here.
        verify:
          $ref: '#/components/schemas/VerifySection'
          description: 'How to verify this attestation and receipt without any other lookup than this response and public_key_url: canonicalization and hash algorithm, this service''s name, and its MCP endpoint.'
        attestation:
          $ref: '#/components/schemas/Attestation'
          description: 'Ed25519 signature over this response (every field above) with the same key as /verify/schema, under the context ''json-schema-verifier/trust-score-attestation/v1''. Verification steps: /.well-known/agent-card.json.'
      type: object
      required:
      - agent_id
      - identity_verified
      - trust_score
      - sample_size
      - confidence_interval_95
      - basis
      - reason
      - factors
      - verified_count
      - passed_count
      - failed_count
      - last_seen
      - computed_at
      - verify
      - attestation
      title: TrustScoreResponse
    Attestation:
      properties:
        algorithm:
          type: string
          const: Ed25519
          title: Algorithm
        key_version:
          type: string
          title: Key Version
        timestamp:
          type: string
          title: Timestamp
        signature:
          type: string
          title: Signature
      type: object
      required:
      - algorithm
      - key_version
      - timestamp
      - signature
      title: Attestation