A2A Agent Card · Verified Digital Agents (VDA)

VDA Witness

Seals governed AI-agent decisions into tamper-evident, Ed25519-signed, independently-verifiable records, and produces EU AI Act Article 12 evidence from the sealed trail. Part of the VDA platform.

✓ Conformant with A2A 1.0.0. This card passes every structural check in the A2A specification’s AgentCard object — a capabilities object, a declared protocolVersion, and a well-formed skills array.
Provider: Verified Digital Agents (VDA) Conformance: Conformant Protocol: 0.2.5 Transport: HTTP+JSON Version: 1.0.0 Host: witness.getvda.ai Skills: 15
Discovery

An A2A client finds this agent by fetching the well-known path on the provider's own host. That is what makes an agent card different from every other agent artifact in this catalog: it is provider-published by construction — it cannot be derived, generated, or reconstructed on a provider's behalf.

https://witness.getvda.ai/.well-known/agent-card.json
Skills (15)

Seal a human-in-the-loop decision seal_hitl_decision

Seals a governance record for a HUMAN decision. Content-based and auditor-reconstructable: it captures the deciding human's identity and role, the disposition and rationale, the policies/SOPs cited AS THE BASIS (by reference, and where possible captured text or hash — policies drift, so an auditor needs the version in force), and content-addressable references (with sha256 hashes) to the system-of-record artifacts the decider SAW at decision time — reservation records, folios, inventory state — NOT the action produced. From the sealed record alone an auditor can verify exactly what state the decider was looking at. Witness seals the ASSERTED actor identity; it does not authenticate the person. Use evidence[].inline to embed a snapshot (≤100KB; bytes are verified against the hash at seal time) when upstream availability isn't guaranteed. If a decision genuinely has no evidentiary basis, state it in evidence_omitted_reason rather than omitting silently. See the MCP `seal_hitl_decision` inputSchema for required fields.

evidencehitlgovernanceaudit

Seal an autonomous agent action seal_agent_action

Seals a record for an action an agent took AUTONOMOUSLY under a governing rule. Records what the agent consumed as two fields split by provenance: `evidence` is EXTERNAL material it saw (content-addressed + hashed — e.g. a whoami response from another service), `parameters` is the COMPUTED arguments it was passed (self-contained, no hash — e.g. requested scopes, jurisdictions). One-question test: exists outside this record? → evidence (hash it); computed/passed as an argument? → parameters. At least one is required (or evidence_omitted_reason). Optionally include agent_context — free-form execution-substrate hints (cloud_run_revision, model_name, region) so an auditor can ask 'was this at a known-buggy revision?'; asserted by you, not verified by Witness. For a human decision use seal_hitl_decision.

evidenceagentgovernanceaudit

Seal an attestation seal_attestation

Seals an assertion that a fact or state held AS OF a point in time — a model passed an evaluation, a card was issued, a key was rotated, a config was live. Not for decisions (use the decision skills). Captures the asserting party, the claim, and the as-of time; supporting external references (evidence) are optional but strengthen it. Cite the framework via governing_basis, or it is sealed as attested-by-the-signing-party, not independently verified by Witness.

attestationed25519audit

Issue an admission credential issue_admission_credential

Issue an agent admission credential — a sealed attestation admitting an agent (subject_did) to a customer environment with a scope, valid until expiry. The Witness record IS the credential (no separate document): enforcers hold only the credential id and check it via check_valid (Contract B); it is revocable via revoke_admission_credential. Sealed by the issuer's Witness account — only that account can revoke. subject_did / environment_id / scope / compliance_mappings are ASSERTED, not authenticated by Witness (the admission workflow establishes them; Witness records the claim). Records are immutable — validity is computed at verify time, never mutated. HOLDER-BINDING: the credential id is a bearer handle — issuing it does not bind the holder; the ENFORCER must separately prove the presenter controls subject_did (see check_valid). PROVISIONAL is representable honestly: sandbox_result.pass may be false and score null ('not run'), and evidence_seal_ref may point at an honest stub — a credential can truthfully record a conditional / not-yet-passed admission rather than forcing a passing claim.

credentialadmissionattestationed25519

Check a credential's validity check_valid

CONTRACT B — the public credential-verification endpoint. Is this admission credential currently valid? PUBLIC, no key: input is a credential_id; anyone holding one can verify it, which is what makes issuer-issued credentials verifiable-by-anyone (their whole value). Witness returns the single canonical verdict — issued ∧ signature verifies ∧ not revoked by the issuer ∧ not expired — so every enforcer is identically correct and the meaning of 'valid' evolves in ONE place, never drifting across independent implementations (the reason this is a skill and not a two-call recipe). Response {valid, code, subject, issuer, environment, scope, expires_at, revoked, revoked_at?, reason_code?, issuer_verified, issuer_verification}; code is 'valid' | 'revoked' | 'expired' | 'not_found' | 'not_credential'. PUBLIC — no key (a credential id is not a secret; CRL/OCSP posture). Cache-Control: private, max-age=60. issuer_verified is a DISTINCT signal from the lifecycle verdict — issuer-authenticity: 'verified' (customer-managed record signed by a key published in issuer_did's DID document — provable even against Witness), 'key_not_in_did_doc' (LOUD: claims an issuer but signed by a key not in its DID — suspicious), 'custodial' (Witness-signed; issuer-authenticity not established, only integrity/anchoring), or 'did_unresolvable' (the check did not complete; not verified AND not forged). Set your own bar: a high-stakes environment may require issuer_verified:true; a low-stakes one may accept custodial. TWO enforcer disciplines the schema teaches: (1) a credential id is a BEARER handle — a valid credential is necessary, NOT sufficient; you MUST separately challenge the presenter to prove control of `subject` (a DID challenge), because validity is not proof the presenter is the subject. (2) Record each check_valid response in YOUR OWN audit log (timestamp, credential_id, response) — Witness's cache and logs tell you what was returned, but only your local record proves what YOU acted on and when, when a regulator later asks how you knew the credential was valid at time T.

credentialverificationrevocationenforcement

Verify a record's issuer-authenticity (verdict only) verify_record_issuer

Is a record's signature by the issuer it claims? PUBLIC, no key. Input is a record_id; the answer is a VERDICT plus the issuer DID and the public key it resolved against — NEVER the record body, decision.inputs, or evidence. General records (attestations, agent_actions) are account-private; this is the ONLY thing about them that is publicly checkable, and the surface is exactly as wide as the question. This is how an enforcer of a privilege-widening event — e.g. a service sealing a genesis authority registration or a baseline promotion ABOUT ITSELF, customer-managed — confirms the issuer signed it, not merely that Witness recorded it, without holding the account's key or seeing the record. Response {record_id, signature_valid, issuer_verified, issuer_verification, issuer_did, signer_key}. Same four states as check_valid's issuer_verified: 'verified' (signing key IS published in the claimed issuer's did:web) | 'key_not_in_did_doc' (LOUD — signed by a key NOT in that DID; suspicious) | 'custodial' (Witness's own key signed it — issuer-authenticity is not the applicable question, a different custody model, not a failure) | 'did_unresolvable' (issuer DID unreachable — the check did NOT complete; treat as neither verified nor forged). The issuer DID is taken from the credential's issuer_did or, for a general record, from the signer's did:web keyId. Cache-Control: public, max-age=60 (no-store while did_unresolvable). ids are unguessable UUIDs; unknown → not_found.

verificationissuer-authenticityenforcementcustody

Revoke an admission credential revoke_admission_credential

Revoke an admission credential your account issued. Only the issuing account may revoke (enforced structurally by comparing sealing accounts, not a DID string). Terminal — re-admission is a NEW credential. Produces a new immutable revocation attestation that supersedes the credential; verify_admission_credential reflects it within the ~60s cache window. Customers who want a credential revoked call the issuing service (onboard.getvda.ai), which owns revocation policy and executes here — customers do not call Witness directly.

credentialrevocationattestation

Revoke an account API key (sealed as an event) revoke_api_key

Revoke one of your account's API keys — the key stops authenticating at once, and the revocation is itself sealed as a key_revocation attestation on your chain. TWO authorities: (1) CONTROLLER-AUTHORIZED, owner self-service, no operator — prepare a key_revocation via /prepare {skill:'revoke_api_key', params:{key_id, revoked_by:{type:'controller'}, reason_code}}, sign the canonical bytes with your BOUND CONTROLLER key, and POST { record } here. Witness verifies the signer IS your bound controller and that the key is yours; the record is customer-managed (owner-signed) so the revocation is provable AGAINST Witness, not merely asserted by it. (2) ADMIN break-glass (operator, x-witness-admin, { key_id }) — sealed custodially, revoked_by.type='operator'; the record honestly shows Witness asserted it. revoked_by.type is the trust distinction, not a code path. Revocation is TOTAL: a revoked key 401s at auth AND its account's records become unfetchable with it — there is NO operator backdoor to read a revoked account's records. Reflected in whoami: a revoked key 401s immediately (no-store); a sibling's ≤60s cached 200 is the only propagation lag.

revocationkey-managementcustodysecurity

Resolve a Witness key — cross-service auth (Contract A) whoami

The SANCTIONED cross-service authorization endpoint. A sibling getvda.ai service that accepts `Authorization: Bearer wtn..` from ITS caller validates that key by calling whoami — Witness is the sole source of truth for its own keys, so no sibling replicates the key store. Returns everything a sibling needs to authorize on IDENTITY, not just presence: account_id (WHO), tier (SEALED|ANCHORED), scopes (WHAT it may do), compliance, key_id, revoked (always false on 200), and expires_at (validity window; null = non-expiring — a revoked or expired key 401s before reaching here). A key can only ever resolve ITSELF — it cannot enumerate other accounts. Any missing/invalid key returns a uniform 401 'unknown or invalid API key' (no existence leak). Available as REST (GET) and as the MCP `whoami` tool; permissively rate-limited per IP and per account.

authcross-servicecompositionsuite

Seal (general-purpose / compatibility) seal

General-purpose seal, retained for backward compatibility and for records that fit none of the shaped skills. PREFER a shaped skill so your record is auditor-reconstructable: seal_hitl_decision (a human decided), seal_agent_action (an agent acted), seal_attestation (you assert a fact/state). Records sealed here carry no record_type and report as unstructured. API key required; no key? see `provisioning.selfServeKey` or the MCP `get_test_key` tool.

evidenceed25519auditcompatibility

Read your own records read

Read back what you've sealed (operational query, account-scoped by your key — never an accountId param). `list_records` returns paginated summaries + the set of chainKeys in your account (discover your own chains); `get_record` returns the FULL signed body of one record. For OFFLINE verification of chain continuity with ZERO calls back to Witness, fetch a self-contained proof bundle: `GET /records/{recordId}?proof=chain` (record + full chain + anchor attestation + did.json) or `GET /chains/{chainKey}/proof` (whole trail). Feed it to `offlineVerify({record, chain, anchor, didDocument})` — verdicts: ANCHORED_VALID / SIGNED_PENDING / BROKEN / INSUFFICIENT_PROOF (the last means proof material was missing, NOT tampering). Distinct from `report` (Article-12 artefact). Foreign/unknown id → not-found (no leak).

readqueryaudit-trail

Self-provision an account (no human) provision

Self-issue a SEALED-tier API key in-band with no human. Pass an Ed25519 controller PUBLIC key (`controllerPublicKeyJwk`) to claim a DURABLE, self-renewable account bound to a key you hold — otherwise the account auto-expires ~7 days. Sealed tier = signed + hash-chained + independently verifiable OFFLINE, but NOT externally anchored (terminal — it stays sealed). The Anchored tier (externally committed, "provable even against us") is concierge-provisioned separately. Then `renew` re-keys the same account forever. See also `provisioning.selfServeKey`.

provisioningself-serveed25519

Renew a key (agent-provable, no human) renew

Get a fresh short-TTL API key for an account you ALREADY control — indefinitely, with no human and no permanent secret. Two steps: POST /renew/challenge {accountId} → nonce; Ed25519-sign `vda.witness.renew/1||` with your controller key; POST /renew {accountId, nonce, signature} → fresh key bound to the SAME account (chains continue, prev-hash unbroken). Bind the controller key at creation via `provisioning.selfServeKey.controllerPublicKeyJwk`.

credentialrenewaled25519self-serve

Verify a record verify

Independently verify a record or chain (Ed25519 signature + hash-chain). No auth.

verificationtamper-evidence

Article 12 Evidence Report report

Generate an EU AI Act Article 12 evidence report from the sealed trail (API key required).

eu-ai-actart-12evidence
Documentation
https://witness.getvda.ai/docs
Evidence. Fetched 2026-09-19 from https://witness.getvda.ai/.well-known/agent-card.json, HTTP 200. The body was saved verbatim and is the sole source for everything on this page — no field is inferred. View the captured card. Providers change what they serve; if this card has moved or changed shape, the provider profile carries the current state as of the last build.

Work with this as data

Every agent card here is available over the APIs.io API and to AI agents over MCP. A2A Agent Cards is not yet its own endpoint on the v1 API. Reach it through catalog search and the tag graph, or the MCP server.

MCP server

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

https://apis.io/mcp

Tools for a2a agent cards

3 MCP tools reach this
  • 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
Search the catalog
curl "https://apis.io/api/v1/search?q=getvda-ai&limit=10"
Everything under a tag
curl "https://apis.io/api/v1/tags/getvda-ai"

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.