API Reference

The identity.app API is split across two domains. Requests and responses use JSON.

Main API
https://identity.app/api/v1

Agents, signatures, consent, identity resolution, disclosure

Ingestion API
https://integrator.identity.app

Event ingestion for integrators

Agent identity

POSThttps://identity.app/api/v1/agents/register

Register a new agent identity. Requires a proof-of-work nonce where SHA-256(publicKey + nonce) starts with 0000.

Request body

FieldTypeDescription
publicKeyrequiredstringBase64-encoded 32-byte Ed25519 public key
powNoncerequiredstringProof-of-work nonce
labeloptionalstringHuman-readable agent name
linkingKeyoptionalstringPre-generated linking key to auto-claim at registration

Response (201)

FieldTypeDescription
didstringDecentralized identifier (did:identity:<id>)
claimTokenstring?One-time token for manual claiming (absent if linkingKey was used)
linkedbooleanWhether the agent was auto-linked to an owner

Example

curl -X POST https://identity.app/api/v1/agents/register \
  -H "Content-Type: application/json" \
  -d '{"publicKey":"<b64>","powNonce":"12345","label":"my-bot"}'
GEThttps://identity.app/api/v1/agents/:id

Resolve an agent's full identity profile scoped to your integrator. The :id parameter accepts a DID or internal agent ID.

Requires Authorization: Bearer <integrator-api-key>

Response (200)

FieldTypeDescription
integratorobject{ id, slug, name }
subjectobject{ type, id, identifier, profile: { did, publicName, handle, status, ... } }
scoreobject?Global reputation: { score, laneScores, updatedAt }
integratorScoreobject?Integrator-scoped: { score, laneScores, environmentCount, updatedAt }
metricBreakdownarrayPer-metric: [{ environmentId, metricKey, totalEvents, weightedContribution, lastEventAt }]
contextKeystringScoring context identifier

Example

curl https://identity.app/api/v1/agents/did:identity:abc123 \
  -H "Authorization: Bearer <integrator-api-key>"
POSThttps://identity.app/api/v1/agents/report

Report an agent for bad behavior. Signed reports (from registered agents) carry higher trust weight than anonymous reports.

Request body

FieldTypeDescription
didrequiredstringDID of the agent being reported
reasonrequiredstringspam, impersonation, malicious, or other
signatureHashoptionalstringThe signature hash that prompted the report
detailsoptionalstringFree-text explanation
reporterDidoptionalstringYour DID (required for signed reports)
signatureoptionalstringEd25519 signature of "report:<targetDid>:<reason>:<signedAt>"
signedAtoptionalnumberTimestamp (required for signed reports)
Signed vs anonymous: If reporterDid, signature, and signedAt are all present, the report is treated as a signed agent report (higher trust, -5 penalty). Otherwise it is an anonymous report (-2 penalty).

Example (signed)

curl -X POST https://identity.app/api/v1/agents/report \
  -H "Content-Type: application/json" \
  -d '{
    "did": "did:identity:target...",
    "reason": "spam",
    "reporterDid": "did:identity:yourDid...",
    "signature": "<b64>",
    "signedAt": 1700000000000,
    "details": "Flooding the network with junk signatures"
  }'

Signatures

POSThttps://identity.app/api/v1/signatures/sign

Record a signed message. The agent must sign payloadHash:signedAt with its Ed25519 private key.

Request body

FieldTypeDescription
didrequiredstringThe agent's DID
payloadHashrequiredstringSHA-256 hex digest of the message content
signaturerequiredstringBase64-encoded Ed25519 signature of "payloadHash:signedAt"
signedAtrequirednumberUnix timestamp in milliseconds
publicNoteoptionalstringHuman-readable label (max 160 chars)

Response (201)

FieldTypeDescription
signatureHashstringUnique hash identifying this signature

Example

curl -X POST https://identity.app/api/v1/signatures/sign \
  -H "Content-Type: application/json" \
  -d '{"did":"did:identity:abc","payloadHash":"<hex>","signature":"<b64>","signedAt":1700000000000}'
GEThttps://identity.app/api/v1/signatures/verify

Look up a signature and get the signing agent's identity, reputation, and verification instructions. Optionally include a bearer key to also get consent status.

Query parameters

FieldTypeDescription
hashrequiredstringThe signature hash to look up

Optional auth

Authorization: Bearer <integrator-api-key>

Response (200)

FieldTypeDescription
validbooleanAlways true for found signatures
signedAtnumberWhen the message was signed (ms)
payloadHashstringSHA-256 hex of the original content
publicNotestring?Agent-provided label
agentobject{ did, publicName, handle, status, activeSince }
ownerobject?{ name, handle } or null if unclaimed
reputationobject?{ score, totalSignatures }
verificationobject{ instructions, algorithm, encoding, payloadHash, verifyUrl, certifyUrl, learnMore }
integratorConsentobject?{ integratorSlug, status } — only with auth
Content verification: Compute SHA-256(originalMessage) (hex-encoded) and compare to payloadHash to independently verify message authenticity.

Example

curl "https://identity.app/api/v1/signatures/verify?hash=<signatureHash>"
POSThttps://identity.app/api/v1/signatures/certify

Record a content certification. Confirms whether the caller's content matches the signed payload, and increments the certification count on a match.

Request body

FieldTypeDescription
signatureHashrequiredstringThe signature hash to certify against
contentHashrequiredstringSHA-256 hex digest of the content you want to verify

Optional auth

Authorization: Bearer <integrator-api-key>

Response (200)

FieldTypeDescription
matchbooleanWhether the content hash matches the signed payload hash
signatureHashstringThe signature hash that was checked
payloadHashstringThe original payload hash
signerobject{ did, signedAt, publicNote }
integratorConsentobject?{ integratorSlug, status } — only with auth

Example

curl -X POST https://identity.app/api/v1/signatures/certify \
  -H "Content-Type: application/json" \
  -d '{"signatureHash":"<hash>","contentHash":"<sha256-hex>"}'

Integrator

POSThttps://identity.app/api/v1/integrators/consent

Set per-agent consent for an integrator. The request must reference a previously recorded signature whose payload matches the canonical consent object.

Request body

FieldTypeDescription
integratorSlugrequiredstringTarget integrator slug
didrequiredstringAgent DID granting/revoking consent
actionrequiredstringallow or revoke
signatureHashrequiredstringSignature hash of canonical consent payload
signedAtrequirednumberTimestamp from the signed consent payload

Response (200)

{
  "did": "did:identity:AGENT",
  "integratorSlug": "example-integrator",
  "status": "allowed",
  "signedAt": 1730000000000
}
GEThttps://identity.app/api/v1/integrators/:slug/disclosure

Public disclosure for an integrator. Shows which actions affect global reputation and which stay local. No auth required.

PublicNo authentication required

Path parameters

FieldTypeDescription
slugrequiredstringIntegrator slug

Response (200)

FieldTypeDescription
integratorobject{ slug, name, domain }
boostingReputationMetricsarrayMapped positive metrics that can improve global reputation
hurtingReputationMetricsarrayMapped negative metrics that can reduce global reputation
neutralReputationMetricsarrayIntegrator-context-only metrics (no global reputation impact)

Example

curl https://identity.app/api/v1/integrators/my-platform/disclosure

Event ingestion

POSThttps://integrator.identity.app/ingest

Ingest events. Accepts a single event object or an array. For agent-subject events, consent must be allowed.

Requires Authorization: Bearer <integrator-api-key>

Request body

Required

FieldTypeDescription
envIdstringEnvironment ID (slug.namespace.version)
externalEventIdstringDeduplication key
eventTypestringDot-notation event type
subjectTypestringhuman, agent, or organization
subjectIdstringSubject's external ID
actorTypestringhuman, agent, organization, or system
actorIdstringWho triggered the event

Optional

FieldTypeDescription
occurredAtnumberUnix timestamp (ms), defaults to now
metricValuesarray[{ metricKey, numberValue?, booleanValue?, enumValue? }]
severitystringlow, medium, or high
counterpartyTypestringOther party type
counterpartyIdstringOther party ID
interactionIdstringGroups related events
dataanyArbitrary JSON metadata

Response (200)

{
  "success": true,
  "count": 1,
  "results": [
    { "externalEventId": "evt_abc123", "inserted": true }
  ]
}

Example

curl -X POST https://integrator.identity.app/ingest \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <integrator-api-key>" \
  -d '{
    "envId": "my-platform.production.v1",
    "externalEventId": "evt_abc123",
    "eventType": "task.completed",
    "subjectType": "agent",
    "subjectId": "did:identity:AGENT_DID",
    "actorType": "human",
    "actorId": "user_123",
    "metricValues": [
      { "metricKey": "tasks_completed", "numberValue": 1 }
    ]
  }'

Error responses

All errors return a JSON object with an error field:

{ "error": "Description of what went wrong" }

400

Missing fields or validation failure

401

Missing or invalid API key

404

Agent or signature not found