FR EN

JSON reference

This section documents the on-the-wire artifacts field by field. Every example is the real shape Agreely's code builds, not an illustration. Read alongside the protocol for the cryptography behind each field.

When a company issues a consent request, Agreely builds a number-free offer, signs its JCS-canonical bytes with the company key, and wraps the signature as a companySig Data Integrity proof. Every value is a string, so the canonical bytes a verifier re-derives can never diverge.

{
  "requestId": "0x4b08245219c0e1a2b3c4d5e6f70819a2b3c4d5e6f70819a2b3c4d5e6f7081234",
  "issuer": "did:web:agreely.ca:c:acme",
  "subject": {
    "ref": "cust_8812",
    "status": "known"
  },
  "consent": {
    "action": "grant",
    "items": [
      {
        "itemId": "0x9a2b3c4d5e6f70819a2b3c4d5e6f70819a2b3c4d5e6f70819a2b3c4d5e6f7081",
        "category": "phone number",
        "purpose": "billing"
      }
    ]
  },
  "nonce": "0x7081234b3c4d5e6f70819a2b3c4d5e6f70819a2b3c4d5e6f70819a2b3c4d5e6f",
  "validUntil": "2031-01-01T00:00:00Z",
  "createdAt": "2026-06-26T15:00:00Z",
  "expiresAt": "2026-07-26T15:00:00Z",
  "companySig": {
    "type": "DataIntegrityProof",
    "cryptosuite": "eddsa-jcs-2022",
    "created": "2026-06-26T15:00:00Z",
    "verificationMethod": "did:web:agreely.ca:c:acme#kms-1",
    "proofPurpose": "assertionMethod",
    "proofValue": "z3Ge8wQ5...base58btc..."
  }
}

Field by field

Field Type Meaning
requestId 0x + 64 hex The protocol handle: 32 fresh random bytes, never derived. The public id everywhere, never an internal uuid.
issuer string The company DID, did:web:agreely.ca:c:{slug}.
subject.ref string The company's own customer reference. Never a citizen DID.
subject.status string known or unonboarded (whether the recipient already has a citizen DID).
consent.action string grant.
consent.items[].itemId 0x + 64 hex A fresh random opaque handle for this item.
consent.items[].category string The normalized category key (lowercased canonical), not the display label.
consent.items[].purpose string The normalized purpose key.
nonce 0x + 64 hex Single-use random nonce, bound into the approval challenge so the answer cannot be replayed.
validUntil RFC 3339 The consent lifespan if approved.
createdAt RFC 3339 When the offer was minted.
expiresAt RFC 3339 The answer deadline (30 days). A pending request past this flips to expired.
companySig object The eddsa-jcs-2022 Data Integrity proof over the offer.

What companySig signs

The signature covers the offer object before companySig is added, that is: requestId, issuer, subject, consent, nonce, validUntil, createdAt, and expiresAt. To verify it, drop companySig (and the at-rest status / result fields), JCS-canonicalize what remains, and check the Ed25519 signature against the company key.

At rest

The object Agreely stores (encrypted under the tenant DEK) is the offer plus three envelope fields, which are not covered by companySig:

{
  "...": "all offer fields above",
  "companySig": { "...": "the proof" },
  "status": "pending",
  "result": { "receipts": null, "settledAt": null }
}

status advances to approved, refused, expired, or revoked_before_action; result is populated when the request settles.

The SDK-facing shapes

The /v1 API returns trimmed views of a request rather than the raw signed object. The issuance response (IssuedRequest) and the list/show view (ConsentRequest) are documented in the API reference and the interactive spec.