iGrant.io consent records (Consent BB individual API)
When to use
When your app must record and manage a user's consent for a data agreement -
allow, read current state, withdraw, show history, or erase (right to be
forgotten). Assumes you already have the individualId (from
igrantio-individuals) and the dataAgreementId you are collecting consent for.
Integrator intake
Ask one question at a time, a recommended default with each; look up facts in
the project, put only decisions to the integrator:
- Environment - demo (
https://demo-api.igrant.io), staging, or a custom
Consent BB deployment (ask its base URL)? Recommend demo to start.
- API key - organisation API key for the Consent Building Block?
Server-side only, never the browser.
- Data agreement(s) - which
dataAgreementId(s) are consents recorded
against? Listed in the iGrant.io admin console; ask the integrator to
paste them.
- Erasure policy - expose "delete all consents" (right to be forgotten)
to end users, or admin-only? Recommend admin-only unless the product
requires self-service.
Prerequisites
individualId - the Consent BB individual for the user (see igrantio-individuals;
resolve it server-side from your session/userId mapping).
dataAgreementId - the data agreement to record consent against.
- Organisation API key - server-side only.
API (Consent BB individual, base /v2)
Auth on every call: Authorization: ApiKey <key> and
X-ConsentBB-IndividualId: <individualId>.
| Method |
Path |
Purpose |
| POST |
/v2/service/individual/record/data-agreement/{dataAgreementId}?revisionId= |
Record consent (first time) |
| GET |
/v2/service/individual/record/data-agreement/{dataAgreementId} |
Read consent for a data agreement |
| GET |
/v2/service/individual/record/consent-record?limit=&offset= |
List all the individual's records |
| PUT |
/v2/service/individual/record/consent-record/{consentRecordId}?individualId=&dataAgreementId=&revisionId= |
Update (allow/withdraw) |
| GET |
/v2/service/individual/record/consent-record/history?limit=&offset= |
Consent change history |
| DELETE |
/v2/service/individual/record |
Delete all records (right to be forgotten) |
Consent record fields: id, dataAgreementId, individualId, optIn (true=allow,
false=withdraw), state (unsigned|signed), sectorPreferences[]. Updating a
signed record invalidates its signature. (Signature/draft endpoints exist for PKI
flows; the reference covers the core opt-in lifecycle.)
Reference
./references:
src/consentClient.ts - dependency-free Consent BB client (consentRecords.*).
src/consent.ts - readConsent, setConsent, giveConsent, withdrawConsent
(create-or-update, so callers don't juggle first-time vs update).
src/consentRouter.ts - Express router exposing clean endpoints; resolves
individualId server-side via an IndividualIdResolver (never trusts the browser).
src/server.ts - example wiring.
Steps
cd references && cp .env.example .env; set OWS_ENV, OWS_API_KEY.
npm install.
- Mount the router with your own resolver (session → userId → individualId):
const client = createConsentClient({ owsBaseUrl: config.owsBaseUrl, apiKey: config.apiKey });
app.use("/", consentRouter(client, (req) => mappingStore.getIndividualId(req.session.userId)));
- Frontend calls
PUT /consents/:dataAgreementId { optIn } to allow/withdraw,
GET /consents/:dataAgreementId to read - no key or individualId in the browser.
Clean-code notes
individualId and the API key are injected server-side; the browser only sends
the dataAgreementId and the opt-in choice.
setConsent hides the create-vs-update branch; the client is the only place
Consent BB paths live.
Validation / done criteria
npm run typecheck passes.
giveConsent then readConsent returns optIn: true; withdrawConsent flips it
to false; history shows the change.
- No API key or raw individualId is present in the browser.
Documentation & workflows
When anything is unclear, consult the iGrant.io documentation before guessing:
1---2name: igrantio-consent-records3description: Record and manage individual consents against a data agreement using the iGrant.io Consent Building Block, given a dataAgreementId and an individualId. Node/TypeScript backend for the individual Consent-Record API: create, read, list, update (allow/withdraw), history, and delete-all (GDPR right to be forgotten). Use when an application must capture and manage a user's consent decisions. Get individualId from igrantio-individuals.4license: Apache-2.05---67# iGrant.io consent records (Consent BB individual API)89## When to use10When your app must **record and manage a user's consent** for a data agreement -11allow, read current state, withdraw, show history, or erase (right to be12forgotten). Assumes you already have the `individualId` (from13`igrantio-individuals`) and the `dataAgreementId` you are collecting consent for.1415## Integrator intake16Ask one question at a time, a recommended default with each; look up facts in17the project, put only decisions to the integrator:181. **Environment** - demo (`https://demo-api.igrant.io`), staging, or a custom19 Consent BB deployment (ask its base URL)? _Recommend demo to start._202. **API key** - organisation API key for the Consent Building Block?21 Server-side only, never the browser.223. **Data agreement(s)** - which `dataAgreementId`(s) are consents recorded23 against? _Listed in the iGrant.io admin console; ask the integrator to24 paste them._254. **Erasure policy** - expose "delete all consents" (right to be forgotten)26 to end users, or admin-only? _Recommend admin-only unless the product27 requires self-service._2829## Prerequisites30- `individualId` - the Consent BB individual for the user (see `igrantio-individuals`;31 resolve it **server-side** from your session/userId mapping).32- `dataAgreementId` - the data agreement to record consent against.33- Organisation API key - server-side only.3435## API (Consent BB individual, base `/v2`)36Auth on every call: `Authorization: ApiKey <key>` **and**37`X-ConsentBB-IndividualId: <individualId>`.3839| Method | Path | Purpose |40| --- | --- | --- |41| POST | `/v2/service/individual/record/data-agreement/{dataAgreementId}?revisionId=` | Record consent (first time) |42| GET | `/v2/service/individual/record/data-agreement/{dataAgreementId}` | Read consent for a data agreement |43| GET | `/v2/service/individual/record/consent-record?limit=&offset=` | List all the individual's records |44| PUT | `/v2/service/individual/record/consent-record/{consentRecordId}?individualId=&dataAgreementId=&revisionId=` | Update (allow/withdraw) |45| GET | `/v2/service/individual/record/consent-record/history?limit=&offset=` | Consent change history |46| DELETE | `/v2/service/individual/record` | Delete all records (right to be forgotten) |4748Consent record fields: `id`, `dataAgreementId`, `individualId`, **`optIn`** (true=allow,49false=withdraw), `state` (`unsigned`|`signed`), `sectorPreferences[]`. Updating a50signed record invalidates its signature. (Signature/draft endpoints exist for PKI51flows; the reference covers the core opt-in lifecycle.)5253## Reference54[`./references`](./references):55- `src/consentClient.ts` - dependency-free Consent BB client (`consentRecords.*`).56- `src/consent.ts` - `readConsent`, `setConsent`, `giveConsent`, `withdrawConsent`57 (create-or-update, so callers don't juggle first-time vs update).58- `src/consentRouter.ts` - Express router exposing clean endpoints; resolves59 `individualId` **server-side** via an `IndividualIdResolver` (never trusts the browser).60- `src/server.ts` - example wiring.6162## Steps631. `cd references && cp .env.example .env`; set `OWS_ENV`, `OWS_API_KEY`.642. `npm install`.653. Mount the router with your own resolver (session → userId → individualId):66 ```ts67 const client = createConsentClient({ owsBaseUrl: config.owsBaseUrl, apiKey: config.apiKey });68 app.use("/", consentRouter(client, (req) => mappingStore.getIndividualId(req.session.userId)));69 ```704. Frontend calls `PUT /consents/:dataAgreementId { optIn }` to allow/withdraw,71 `GET /consents/:dataAgreementId` to read - no key or individualId in the browser.7273## Clean-code notes74- `individualId` and the API key are injected server-side; the browser only sends75 the dataAgreementId and the opt-in choice.76- `setConsent` hides the create-vs-update branch; the client is the only place77 Consent BB paths live.7879## Validation / done criteria80- `npm run typecheck` passes.81- `giveConsent` then `readConsent` returns `optIn: true`; `withdrawConsent` flips it82 to `false`; `history` shows the change.83- No API key or raw individualId is present in the browser.8485## Documentation & workflows8687When anything is unclear, consult the iGrant.io documentation before guessing:8889- iGrant.io developer APIs (index): https://docs.igrant.io/docs/developer-apis90- Getting started: https://docs.igrant.io/docs/get-started/91- Consent management - individual API: https://docs.igrant.io/docs/category/consent-management-individual-api/organisation92- Consent management - admin API: https://docs.igrant.io/docs/category/consent-management-admin-api/data-agreement