Broker a fullmakt: bind an agent principal to an Altinn systembruker delegation
Fullmakt Rails core flow. Given an existing agent principal (created with POST /api/v1/fullmakt/principals — same fullmakt:write scope), a customer org_number, and a scope set, Apier brokers an Altinn systembruker delegation and binds the returned system_user_id back onto the principal. Ordering contract: Altinn is called FIRST; only on upstream success is the delegation row persisted, then the principal binding written, then a 'pending' principal flipped to 'active'. Principal activation always reflects a DURABLE binding — if a local follow-up write degrades after the upstream call succeeded, the response is still 201 (the brokered delegation and its approval URL must not be lost) and the degradation is surfaced as a machine-readable token in data.warnings so the caller can reconcile instead of blind-retrying (a blind retry would broker a SECOND delegation). The principal binding is write-once: a principal already bound to a different systembruker keeps its binding and the response carries principal_already_bound_mismatch. The delegation itself starts as 'pending' until the company's signing authority approves the delegation_url. The integration runs against the mock Altinn adapter until live partner validation clears; the response shape is identical in both modes. Recorded in the append-only audit log as fullmakt.request.
Request
- Base URL: https://www.apier.no
- URL: https://www.apier.no/api/v1/fullmakt/request
- Auth: HTTP bearer
Headers
Optional client-chosen key that makes this write safely retriable. When the same key is presented on a subsequent request with the same body, the gateway returns the original response (with Idempotent-Replay: true) instead of re-executing the write. Reservation is scoped to (consumer, endpoint, key) so the same key on different endpoints or different consumers does not collide. TTL: 24 hours. The key must be 1–255 printable ASCII characters — a v4 UUID or ULID is the recommended format. Keys are SHA-256 hashed before storage so they may safely carry client-internal identifiers.
OPTIONAL forensic-only attestation: the agent vendor / framework that issued this request (e.g. anthropic, openai, langchain). Persisted to audit_log.agent_vendor and mcp_query_log.agent_vendor; never used for authorization, scope, rate-limit, or idempotency decisioning. The server strips ASCII control chars (0x00–0x1F + 0x7F), Unicode NEL / line / paragraph separators, and BOM before persistence; values exceeding 64 UTF-8 BYTES are byte-boundary clamped (a non-ASCII string declared at 64 chars may exceed the 64-byte ceiling and be clamped further). NEVER echoed in any response body, response header, _meta block, error message, or Sentry payload — one-way capture. Omitting this header writes SQL NULL to the persisted columns. The MCP transport equivalent is clientInfo.attestation.vendor.
OPTIONAL forensic-only attestation: the agent model id (e.g. claude-opus-4-7, gpt-4o-mini-2024-07-18). Persisted to audit_log.agent_model and mcp_query_log.agent_model; identical sanitisation + clamp + non-echo rules as X-Agent-Vendor (control-char strip, 128-UTF-8-BYTE ceiling, never visible on any response). Forensic-only: never used for authorization, scope, rate-limit, or idempotency decisioning.
OPTIONAL forensic-only attestation: an opaque agent-side run / trace identifier (e.g. a LangSmith run id, a vendor-specific session id). Persisted to audit_log.agent_run_id and mcp_query_log.agent_run_id; identical sanitisation + clamp + non-echo rules as X-Agent-Vendor (control-char strip, 256-UTF-8-BYTE ceiling, never visible on any response). Forensic-only: never used for authorization, scope, rate-limit, or idempotency decisioning.
Request body
Example request
{
"agent_principal_id": "11111111-1111-4111-8111-111111111111",
"org_number": "999999999",
"scopes": [
"altinn:accessmanagement/authorizedparties.read"
],
"validity_days": 365,
"label": "Innkjøpsagent (Oslo HQ)"
}Response
Delegation brokered. data.status is 'pending' until the company's signing authority approves data.delegation_url. data.agent_principal carries the principal's POST-request lifecycle state (bound system_user_id + status) so no follow-up GET is needed. data.warnings is ALWAYS present — empty on the clean path; non-empty when a local follow-up write degraded after the upstream broker succeeded (see the enum descriptions). A 201 with warnings still means the Altinn delegation EXISTS — reconcile, never blind-retry.
Example response
{
"data": {
"system_user_id": "mock_su_11111111-1111-1111-1111-111111111111",
"signed_receipt": {
"signature": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
}
},
"_meta": {
"rulebook_version": "v1.0.0",
"source": "apier.no",
"data_source": "Brønnøysund Enhetsregisteret + Apier Universal Rulebook",
"schema_version": "1.0.0",
"legal_basis": "NLOD — public registry reuse",
"response_timestamp": "2026-04-24T12:00:00.000Z",
"response_hash": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
"source_snapshot_id": "brreg-2026-04-24T02:00:00.000Z",
"cost_nok": 0.5,
"wallet_remaining_nok": 9.5,
"spend_cap_remaining_nok": 12.5
}
}Changes
No recorded changes to this operation across all 1 revision of this API.