Reference

API Reference

A small, REST-ish surface over https://api.fidacy.com. JSON in, JSON out. Bearer (or x-api-key) auth on every call. All endpoints are organization-scoped and versioned under /v1.

Conventions

  • ·Base URL, https://api.fidacy.com.
  • ·Auth, Authorization: Bearer fky_live_… or x-api-key. Missing/invalid → 401; wrong scope → 403.
  • ·Idempotency, assessing the same mandate twice returns the original verdict (keyed by the mandate's content hash). No duplicate decisions.
  • ·Health, GET /health and GET /.well-known/jwks.json are public.
  • ·OpenAPI, the full machine-readable spec (3.1) is at /openapi.json. Import it into Postman, Insomnia, or a codegen toolchain.

Assess

POST/v1/assess

The core call. Scope assess:write. Validates the mandate, runs KYA → policy → risk → sign → audit, and returns the decision plus the rich outcome. Add an A2A-Version header or a2a block to engage A2A.

Request body

FieldTypeNotes
mandateobjectThe AP2 mandate / action. Required.
kindstringAction supertype. Defaults to ap2_payment.
mandateTypestringAP2 type; derived from the vct when omitted.
a2aobjectOptional A2A context (task_id, context_id, …).
idempotency_keystringOptional; echoed back.

Response (200)

FieldMeaning
decisionapprove | review | deny
score0-100 risk score
assessmentIdFirst-class assessment id (read back later)
mandateIdThe stored mandate id
riskPayloadJwsThe signed Risk Payload (compact JWS, EdDSA)
mandateYour mandate with risk_data injected, forward this
outcomeThe rich, versioned outcome object (below)

The outcome object

{
  "object": "assessment",
  "id": "asmt_…", "created": "…", "livemode": true, "kind": "ap2_payment",
  "outcome": { "decision": "approve", "risk_level": "normal",
               "risk_score": 12, "reason": "approved", "policy_version": 3 },
  "confidences": { "agent_identity": 1, "mandate_validity": 1,
                   "policy_adherence": 1, "behavioral_risk": 0.8, "recipient_risk": 0.8 },
  "signals": [ { "category": "identity", "type": "…", "severity": "low" } ],
  "rejection_reasons": [ { "key": "…", "category": "…", "description": "…" } ],
  "risk_payload": { "jws": "…", "kid": "…", "alg": "EdDSA", "verify_url": "…/jwks.json" },
  "audit": { "entry_id": "ae_…", "sequence": 41, "status": "pending" },
  "refinement": { "status": "pending" } | null,
  "agent": { "id": "agt_…", "trust_score": 72, "risk_tier": "trusted" } | null,
  "latency_ms": 9
}
  • ·risk_level is the worst-signal-dominates band: normal / elevated / highest (deny is always highest).
  • ·audit.status starts pending and becomes anchored once the chain is sealed, the entry_id is stable across the transition.
  • ·refinement.status is pending when an async reasoning pass is queued (review band), else null.

Assessments

GET/v1/assessments
GET/v1/assessments/:id

Scope assess:read. Assessments are first-class objects; the full outcome is reconstructed deterministically from the stored record. The list supports filters (status, agent, kind, from/to) and cursor pagination.

Agents & keys (KYA)

POST/v1/principals
POST/v1/agents
POST/v1/agents/:id/keys
POST/v1/agents/verify-card

Register the accountable principal, the agent that represents it, and the public keysit signs with (stored with their RFC 7638 thumbprint for O(1) match). Verify an A2A Agent Card with verify-card, see A2A.

Mandates

GET/v1/mandates
GET/v1/mandates/:id

Read the mandates the engine has stored and assessed. Each mandate is unique per organization by its canonical content hash.

Policies

GET/v1/policies
POST/v1/policies
POST/v1/policies/:id/activate
POST/v1/policies/:id/backtest

Scope policy:write to mutate, policy:read to list. Create a draft, backtest it against your history, then activate it (one active policy per org). Rules:

{ "name": "eu-cards-v3", "rules": {
    "max_amount": 1000000, "currencies": ["EUR","GBP"],
    "geo": { "allow": ["EU"] }, "velocity": { "window": "1h", "max": 20 }
}, "activate": false }

Audit

GET/v1/audit
POST/v1/audit/verify

Scope assess:read. List the hash-chained trail and verify its integrity, the engine recomputes every entry hash and checks the chain links, returning the first break (if any). Verification is deterministic and reproducible offline from the same rows.

Webhooks

POST/v1/webhook-endpoints
GET/v1/webhook-endpoints

Register signed event delivery, see the dedicated Webhooks guide.

Errors

StatusMeaning
400Malformed request, unknown mandate type, or A2A version mismatch.
401Missing or invalid credential.
403The key lacks the required scope.
404Not found in your organization.
422The mandate failed schema validation.
500Internal error, never returns approve; safe state is review.
503Database or signing key temporarily unavailable.
A 500/503 never produces an approval. If the engine cannot complete the pipeline safely, it degrades to review or returns an error, by construction.