iGrant.io individuals (Consent BB admin Individual API)
When to use
When your app onboards a user, create a matching individual in the iGrant.io
Consent Building Block and store the returned individualId against your own
userId. That mapping is what later lets igrantio-consent-records record and
manage consents for the right person.
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? From
your iGrant.io organisation account; server-side only, never the browser.
- Mapping storage - where does the
userId to individualId mapping
live: a column on the existing users table (recommended) or a separate
store?
The mapping (the important part)
your users table Consent BB
+----------+-------------+ +---------------------------+
| user_id | individual | <──────► | individual { id, ... } |
| u_123 | 6541...cd | | externalId = "u_123" |
+----------+-------------+ +---------------------------+
Persist individualId in YOUR database keyed by your userId. The reference uses
externalId = your userId so the individual is also recoverable from OWS if the
local mapping is ever lost.
API (Consent BB admin, base /v2, Authorization: ApiKey <key>)
| Method |
Path |
Purpose |
| POST |
/v2/config/individual |
Create individual → returns individual.id |
| GET |
/v2/config/individual/{id} |
Read individual |
| PUT |
/v2/config/individual/{id} |
Update individual |
| GET |
/v2/config/individuals?limit=&offset=&externalIndividualId= |
List (find by your userId) |
Individual fields: name, email, phone (required), externalId,
externalIdType, identityProviderId, iamId, mapperId, deviceType, …
Reference
./references:
src/consentClient.ts - dependency-free Consent BB client (individuals.* + consentRecords.*).
src/mappingStore.ts - IndividualMappingStore (userId ↔ individualId); in-memory + DB-swappable.
src/onboarding.ts - ensureIndividual(client, store, userId, profile): idempotent (local mapping → lookup by externalId → create).
src/server.ts - example onboarding endpoints (POST /individuals/onboard, GET /individuals/me).
Steps
cd references && cp .env.example .env; set OWS_ENV (demo|staging), OWS_API_KEY.
npm install.
- In your authenticated signup handler:
const client = createConsentClient({ owsBaseUrl: config.owsBaseUrl, apiKey: config.apiKey });
const individualId = await ensureIndividual(client, store, session.userId, { name, email, phone });
// store.set already persisted userId -> individualId; save it in your users table too
userId must come from your session - never from request input.
Clean-code notes
- The client is the only place Consent BB paths live; onboarding logic is one
idempotent function; the mapping store is an interface you back with your DB.
- The org API key stays server-side; browsers never call the Consent BB directly.
Validation / done criteria
npm run typecheck passes.
- Onboarding the same user twice returns the same
individualId and creates one
individual (idempotent).
- Your DB holds
userId → individualId after onboarding.
Documentation & workflows
When anything is unclear, consult the iGrant.io documentation before guessing:
1---2name: igrantio-individuals3description: Onboard application users into the iGrant.io Consent Building Block as "individuals" and keep a mapping between your own userId and the returned individualId. Node/TypeScript backend for the Consent BB admin Individual API (create, read, update, list). Use when an application signs up users and must create a corresponding individual so GDPR consents can later be recorded against a data agreement. Pairs with igrantio-consent-records.4license: Apache-2.05---67# iGrant.io individuals (Consent BB admin Individual API)89## When to use10When your app onboards a user, create a matching **individual** in the iGrant.io11Consent Building Block and store the returned `individualId` against your own12`userId`. That mapping is what later lets `igrantio-consent-records` record and13manage consents for the right person.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? From21 your iGrant.io organisation account; server-side only, never the browser.223. **Mapping storage** - where does the `userId` to `individualId` mapping23 live: a column on the existing users table (recommended) or a separate24 store?2526## The mapping (the important part)27```28your users table Consent BB29+----------+-------------+ +---------------------------+30| user_id | individual | <──────► | individual { id, ... } |31| u_123 | 6541...cd | | externalId = "u_123" |32+----------+-------------+ +---------------------------+33```34Persist `individualId` in YOUR database keyed by your `userId`. The reference uses35`externalId = your userId` so the individual is also recoverable from OWS if the36local mapping is ever lost.3738## API (Consent BB admin, base `/v2`, `Authorization: ApiKey <key>`)39| Method | Path | Purpose |40| --- | --- | --- |41| POST | `/v2/config/individual` | Create individual → returns `individual.id` |42| GET | `/v2/config/individual/{id}` | Read individual |43| PUT | `/v2/config/individual/{id}` | Update individual |44| GET | `/v2/config/individuals?limit=&offset=&externalIndividualId=` | List (find by your userId) |4546Individual fields: `name`, `email`, `phone` (required), `externalId`,47`externalIdType`, `identityProviderId`, `iamId`, `mapperId`, `deviceType`, …4849## Reference50[`./references`](./references):51- `src/consentClient.ts` - dependency-free Consent BB client (`individuals.*` + `consentRecords.*`).52- `src/mappingStore.ts` - `IndividualMappingStore` (userId ↔ individualId); in-memory + DB-swappable.53- `src/onboarding.ts` - **`ensureIndividual(client, store, userId, profile)`**: idempotent (local mapping → lookup by externalId → create).54- `src/server.ts` - example onboarding endpoints (`POST /individuals/onboard`, `GET /individuals/me`).5556## Steps571. `cd references && cp .env.example .env`; set `OWS_ENV` (demo|staging), `OWS_API_KEY`.582. `npm install`.593. In your **authenticated** signup handler:60 ```ts61 const client = createConsentClient({ owsBaseUrl: config.owsBaseUrl, apiKey: config.apiKey });62 const individualId = await ensureIndividual(client, store, session.userId, { name, email, phone });63 // store.set already persisted userId -> individualId; save it in your users table too64 ```65 `userId` must come from your session - never from request input.6667## Clean-code notes68- The client is the only place Consent BB paths live; onboarding logic is one69 idempotent function; the mapping store is an interface you back with your DB.70- The org API key stays server-side; browsers never call the Consent BB directly.7172## Validation / done criteria73- `npm run typecheck` passes.74- Onboarding the same user twice returns the same `individualId` and creates one75 individual (idempotent).76- Your DB holds `userId → individualId` after onboarding.7778## Documentation & workflows7980When anything is unclear, consult the iGrant.io documentation before guessing:8182- iGrant.io developer APIs (index): https://docs.igrant.io/docs/developer-apis83- Getting started: https://docs.igrant.io/docs/get-started/84- Consent management - individual API: https://docs.igrant.io/docs/category/consent-management-individual-api/organisation85- Consent management - admin API: https://docs.igrant.io/docs/category/consent-management-admin-api/data-agreement