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.
Core concepts
- DID — a self-certifying
did:keyidentity (Ed25519). The public key is derived from the DID, so signatures verify with no lookup. - Credential — a signed, scoped grant of authority (W3C VC), canonicalized with RFC 8785.
- Attestation — a payer-signed record of a settled outcome, appended to the transparency log.
- Reputation — a Sybil-resistant score (EigenTrust + a stake-weighted Bayesian interval) computed from outcomes.
Agents
Register an agent. The caller proves it holds the DID's private key by signing the canonical registration payload.
| field | description |
|---|---|
| did | the agent's did:key |
| publicKeyJwk | the agent's public key (must match the DID) |
| name, principalDid, stake, verified | agent metadata |
| ts, signature | timestamp and proof-of-possession signature |
List registered agents.
Fetch a single agent by DID.
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": { ... } } }
Verify a credential's signature and revocation status. Returns { "valid": true } or { "valid": false, "reason": "..." }.
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
Record a settled outcome, signed by the payer. Appends to the Merkle log and returns a verifiable inclusion proof.
| field | description |
|---|---|
| from, to | payer and provider DIDs |
| rail, value | e.g. x402, 40 |
| outcome | success · dispute · fail |
| ts, signature | timestamp and the payer's signature |
Returns { position, size, root, proof, record }.
Reputation
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 }
Returns reputation for all agents.
Transparency log
Returns the current log size and Merkle root, with an operator-signed tree head when a signer is configured.
Verify an inclusion proof: send { record, proof, root }, receive { "included": true }.
Usage & metering
Returns this tenant's billable call counts, broken down by endpoint — the basis for usage-based billing.
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"]).
{ "subjectDid": "did:key:z6Mk...", "action": "data_export", "jurisdiction": "EU" }
// -> { "allowed": false, "required": ["GDPR"], "held": [], "missing": ["GDPR"] }
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.
{ "from": "did:key:...", "to": "did:key:...", "amount": 50, "rail": "x402",
"evidenceHash": "…", "ts": 1733650000000, "signature": "…",
"jurisdiction": "EU", "action": "data_export" } // -> ESCROWED + proof
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.
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": "…" }
An arbiter resolves it (signed): resolution is SETTLED, REFUNDED, or REJECTED. The outcome is written back to reputation and logged.
Monitoring
Returns agents whose reputation has dropped below a threshold — a read-only anomaly report for risk teams.
Define your own policy (operator). { "jurisdiction": "US", "action": "kyc_share", "requires": ["SOC2"] }. Custom policies are merged with the built-in defaults.
Arbiters
Only authorized arbiters may resolve disputes. An operator registers the arbiter DIDs they trust.
{ "did": "did:key:z6Mk...", "label": "Ops escalation" }
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.
// -> { "from": m, "to": n, "first": "<root@m>", "second": "<root@n>", "proof": ["…"] }
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.
// 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).
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.
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.
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.
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:
Link a Signefora DID to its identity on an external platform — this is what makes reputation portable:
{ "did": "did:key:z6Mk...", "connector": "solana_registry", "externalId": "sol_agent_777" }
Ingest — any platform pushes a normalized trust event; Signefora resolves the external id to a DID, logs it, and feeds reputation:
{ "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:
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.
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.
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.
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.
{ "requesterDid":"did:key:…", "respondentDid":"did:key:…", "reason":"non-delivery",
"evidenceHash":"sha256:…", "ts": 1730000000000, "signature":"…" }
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.
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.
Errors
| code | meaning |
|---|---|
| 400 | malformed request, stale timestamp, or invalid credential |
| 401 | missing/invalid API key, or a signature that doesn't match the DID |
| 403 | the agent is revoked |
| 404 | unknown agent |
| 409 | already registered, or a replayed signature |
| 429 | rate limit exceeded |