Documentation

Issue agent identities, verify credentials, record outcomes, and query reputation — through one rail-neutral API.

Quickstart

Every request is sent to your Signefora deployment's base URL, for example https://signefora.com. All API routes live under /v1 and require an API key. The dashboard and health check are public.

1 · Get an API key

An operator provisions a tenant, which returns an API key once. Keys look like sk_live_<keyId>.<secret>.

2 · Create an agent (non-custodial)

Agents generate their own keys locally and register with a proof-of-possession signature. Using the bundled client:

node client/agent-cli.js keygen
node client/agent-cli.js register \
  --api https://signefora.com \
  --key sk_live_... \
  --name Atlas --principal did:org:acme --stake 500 --verified

3 · Make an authenticated call

curl https://signefora.com/v1/agents \
  -H "Authorization: Bearer sk_live_..."

Authentication

Authenticate every /v1 request with a Bearer token:

Authorization: Bearer sk_live_<keyId>.<secret>

Keys carry a public keyId used for lookup and a secret that is stored only as a SHA-256 hash and compared in constant time. Requests are rate-limited per tenant via a token bucket.

The substrate is non-custodial: it never receives an agent's private key. Agents sign locally; Signefora only verifies signatures against the DID.

Core concepts

Agents

POST /v1/agents

Register an agent. The caller proves it holds the DID's private key by signing the canonical registration payload.

fielddescription
didthe agent's did:key
publicKeyJwkthe agent's public key (must match the DID)
name, principalDid, stake, verifiedagent metadata
ts, signaturetimestamp and proof-of-possession signature
GET /v1/agents

List registered agents.

GET /v1/agents/:did

Fetch a single agent by DID.

Credentials

POST /v1/credentials

Store a client-signed verifiable credential after verifying its signature.

{ "credential": { "issuer": "did:key:z6Mk...", "credentialSubject": { "id": "did:key:...", "action": "purchase.data", "maxPerTx": "5.00 USDC" }, "proof": { ... } } }
POST /v1/credentials/verify

Verify a credential's signature and revocation status. Returns { "valid": true } or { "valid": false, "reason": "..." }.

Revocations

POST /v1/revocations

Revoke a credential or an agent instantly, before its natural expiry.

{ "credentialId": "urn:cred:abc123", "reason": "compromised" }
// or
{ "subjectDid": "did:key:z6Mk...", "reason": "decommissioned" }

Attestations

POST /v1/attestations

Record a settled outcome, signed by the payer. Appends to the Merkle log and returns a verifiable inclusion proof.

fielddescription
from, topayer and provider DIDs
rail, valuee.g. x402, 40
outcomesuccess · dispute · fail
ts, signaturetimestamp and the payer's signature

Returns { position, size, root, proof, record }.

Reputation

GET /v1/reputation/:did

Returns a score, standing, and a credible interval:

{ "did": "did:key:z6Mk...", "score": 0.864, "standing": "trusted",
  "mean": 0.91, "lower": 0.82, "upper": 0.97, "eigen": 1.0, "observations": 12 }
GET /v1/reputation

Returns reputation for all agents.

Transparency log

GET /v1/log/root

Returns the current log size and Merkle root, with an operator-signed tree head when a signer is configured.

POST /v1/log/verify

Verify an inclusion proof: send { record, proof, root }, receive { "included": true }.

Usage & metering

GET /v1/usage

Returns this tenant's billable call counts, broken down by endpoint — the basis for usage-based billing.

GET /healthz

Public health check. Reports the active database, cache, and signer, plus the current signed tree head.

Compliance

Gate an agent's action against declarative policy. An agent satisfies a policy by holding non-revoked credentials carrying the required compliance tags (e.g. a credential with credentialSubject.compliance: ["GDPR"]).

POST /v1/compliance/check
{ "subjectDid": "did:key:z6Mk...", "action": "data_export", "jurisdiction": "EU" }
// -> { "allowed": false, "required": ["GDPR"], "held": [], "missing": ["GDPR"] }
This is the enforcement + evidence mechanism for a compliance program — it records, in the transparency log, that an agent held the right credentials when it acted. It is not, by itself, legal compliance.

Escrow

Move value into escrow against an evidence hash, then settle or refund. Each transition is signed by the payer and appended to the Merkle log with an inclusion proof. Passing jurisdiction + action on commit runs the compliance gate first.

POST /v1/escrow
{ "from": "did:key:...", "to": "did:key:...", "amount": 50, "rail": "x402",
  "evidenceHash": "…", "ts": 1733650000000, "signature": "…",
  "jurisdiction": "EU", "action": "data_export" }   // -> ESCROWED + proof
POST /v1/escrow/:id/settle
POST /v1/escrow/:id/refund

Both take { ts, signature } signed by the payer. Settling records a successful outcome that feeds the provider's reputation. State machine: ESCROWED → SETTLED | REFUNDED | DISPUTED.

GET /v1/escrow
GET /v1/escrow/:id

Disputes

POST /v1/disputes

A party to a commitment opens a dispute (signed by the initiator); the commitment moves to DISPUTED.

{ "commitmentId": "cmt_…", "initiatorDid": "did:key:…", "reason": "non-delivery",
  "ts": …, "signature": "…" }
POST /v1/disputes/:id/resolve

An arbiter resolves it (signed): resolution is SETTLED, REFUNDED, or REJECTED. The outcome is written back to reputation and logged.

GET /v1/disputes
GET /v1/disputes/:id

Monitoring

GET /v1/governance/monitor?threshold=0.2

Returns agents whose reputation has dropped below a threshold — a read-only anomaly report for risk teams.

POST /v1/compliance/policies

Define your own policy (operator). { "jurisdiction": "US", "action": "kyc_share", "requires": ["SOC2"] }. Custom policies are merged with the built-in defaults.

GET /v1/compliance/policies

Arbiters

Only authorized arbiters may resolve disputes. An operator registers the arbiter DIDs they trust.

POST /v1/arbiters
{ "did": "did:key:z6Mk...", "label": "Ops escalation" }
GET /v1/arbiters

A resolution signed by a DID that isn't a registered arbiter is rejected (403). Add arbiters from the CLI too: node src/admin.js add-arbiter <did> "label".

Consistency proofs

Prove the log is strictly append-only between two sizes — that nothing earlier was rewritten. This is the cryptographic backbone of the "tamper-evident" guarantee.

GET /v1/log/consistency?from=<m>&to=<n>
// -> { "from": m, "to": n, "first": "<root@m>", "second": "<root@n>", "proof": ["…"] }
POST /v1/log/consistency/verify

Send the proof back to confirm { "consistent": true } — or, better, verify it yourself with the bundled offline checker so you never have to trust the server.

Audit export

Pull a portable, self-verifying bundle of every logged event touching an agent or a commitment: each event plus its Merkle inclusion proof, under the operator-signed tree head.

GET /v1/audit/agent/:did
GET /v1/audit/commitment/:id
// save the response, then verify offline — no trust in the operator required:
node client/verify-audit.js bundle.json   // exits 0 only if every proof + the signed head check out

Rails (rail-neutral)

Signefora records trust on top of any rail and never moves or holds funds. The registry includes African mobile money (M-Pesa, MTN MoMo, Airtel Money, and more), aggregators (Paystack, Flutterwave), and global rails (x402, AP2, card, bank).

GET /v1/rails

Know Your Agent

One portable profile combining identity, reputation, transaction history, rails seen, compliance tags, and any active fraud flags. A revoked agent shows revoked; an actively flagged agent shows flagged.

GET /v1/kya/:did

Trust passport

An operator-signed, portable snapshot of an agent's standing that a counterparty in another market verifies offline — no call back to Signefora. The only trust anchor is Signefora's operator public key, pinned out-of-band.

POST /v1/passports/:did
POST /v1/passports/verify
node client/verify.js passport passport.json --operator operatorKey.json   // verifies with no server

Fraud bureau

Raise a shared negative signal against an agent (fraud, chargeback, abuse, sanctions). Flags are appended to the transparency log and visible to all key-holders — the bureau effect.

POST /v1/flags
GET /v1/flags/:did
POST /v1/flags/:id/clear

Interoperability hub

Signefora is the neutral ground other agent platforms plug into, so an agent's reputation is portable across them. It speaks the open A2A (Agent2Agent) standard natively and bridges proprietary platforms (Solana registry, Mastercard, Visa, AP2, x402, Ant AMP) via connectors. See the supported list and each connector's status:

GET /v1/connectors

Link a Signefora DID to its identity on an external platform — this is what makes reputation portable:

POST /v1/links
{ "did": "did:key:z6Mk...", "connector": "solana_registry", "externalId": "sol_agent_777" }
GET /v1/links/:did

Ingest — any platform pushes a normalized trust event; Signefora resolves the external id to a DID, logs it, and feeds reputation:

POST /v1/ingest
{ "connector": "x402", "event": { "payer": "0xWallet", "payee": "did:key:...", "amount": 50, "status": "settled" } }

Export — a resolvable A2A trust card any agent platform can read for an agent:

GET /v1/a2a/:did/trust

Billing

Signefora meters billable events per tenant and turns them into a bill using a configurable plan (pay-as-you-go or a tier with included volume + overage). Signefora never charges a card itself — it computes the amount owed; collection happens at your provider or by invoice.

GET /v1/billing — a tenant's own current invoice

Owner-only (admin token): list plans, configure how you get paid (references only, never full bank/card numbers), assign a tenant's plan, and see what everyone owes.

GET /admin/plans
GET /admin/payout   POST /admin/payout
POST /admin/billing/plan
GET /admin/billing

Transactions (per-agent ledger)

Every trust-relevant event recorded for an agent — outcomes, escrow, disputes, flags, mediation, cross-platform ingests — for investigating behaviour. Reflects what was recorded on Signefora.

GET /v1/agents/:did/transactions
GET /v1/my/agents

Mediation (agent-initiated)

An agent can request mediation against another agent by signing the request with its own key — no owner/tenant registration required. The request is logged and an arbiter/operator resolves it.

POST /mediation/request — public; requester signs the payload
{ "requesterDid":"did:key:…", "respondentDid":"did:key:…", "reason":"non-delivery",
  "evidenceHash":"sha256:…", "ts": 1730000000000, "signature":"…" }
GET /v1/mediations

Standards interop: A2A & ERC-8004

Signefora sits on top of the open agent-trust standards. It produces A2A AgentCards and ERC-8004 registration files + keccak256-hashed reputation feedback (publishable on-chain with your own wallet), and ingests them so on-chain / A2A agents gain Signefora scoring, compliance, and the Africa layer. Signefora holds no keys and pays no gas.

GET /v1/a2a/:did/card — A2A AgentCard with a Signefora trust extension
POST /v1/a2a/import — bind an A2A identity to a Signefora DID
GET /v1/erc8004/:did/registration — identity-registry file
GET /v1/erc8004/:did/feedback — signed reputation feedback (value, valueDecimals, fileHash)
GET /v1/erc8004/:did/evidence — the off-chain evidence file the fileHash commits to
POST /v1/erc8004/ingest — fold on-chain identity/feedback into Signefora

Jurisdiction & geo

Signefora detects the request's country (from your CDN/proxy header such as cf-ipcountry, or an explicit country field) and maps it to a regulatory regime / policy pack — EU→GDPR, UK, US, Brazil, India, Nigeria, Kenya, South Africa, Ghana, and a safe GLOBAL baseline for anything unmapped, so it auto-fits anywhere. Packs are policy configuration, not legal advice; validate per market.

GET /v1/jurisdiction?country=DE → detected country + regime + pack
GET /v1/geo → transaction/fraud counts by country (powers the maps)

Errors

codemeaning
400malformed request, stale timestamp, or invalid credential
401missing/invalid API key, or a signature that doesn't match the DID
403the agent is revoked
404unknown agent
409already registered, or a replayed signature
429rate limit exceeded
Need something that isn't here yet? This reference covers the live API surface of your deployment. As the platform grows (staking economics, witnessed log anchoring), new endpoints will be documented here.