# Taifa Identity full public documentation # What Identity owns Taifa Identity has four service boundaries. The Go authentication service issues OIDC tokens and checks credentials. Its separate Svelte authentication UI owns the central sign-in journey. The Python management service reviews people, Institutions, projects, and product eligibility. The Svelte portal owns account and management workflows plus its own product session. Each integrated product still owns its accounts, roles, tenant filtering, and protected resources. ## Choose the right boundary | Work | Owner | | --- | --- | | Password, TOTP, passkey challenge, authorization code, ID and access token | Authentication issuer | | Staff sponsorship, project approval, account-link review, lifecycle events | Management service | | Central sign-in forms, browser binding, CSRF and central session handoff | Authentication UI and its backend | | Portal login transaction, callback, product session and account screens | Portal backend and UI | | Local account, product roles, records, sessions, and access checks | Your application | An OIDC sign-in proves the user's identity. It does not create a product role or make an Institution membership effective. A product checks its local authorization and current lifecycle state before granting access. ## How shared sign-in works 1. A registered application creates its own login transaction, state, nonce and PKCE verifier, then redirects the browser to the configured Taifa issuer. 2. The issuer and central authentication UI check the current session and the application's required authentication strength. A usable central session can avoid another password or passkey prompt; fresh or stronger authentication may still be required. 3. The issuer returns a one-use authorization code to that application's exact registered callback. The application redeems it using the original verifier and validates the signed response. 4. The application resolves the exact `(issuer, subject)` account link, checks current project and Institution access, and creates its own local session. 5. A second registered application repeats this flow using its own client and callback. It can reuse the central sign-in session, while keeping its own cookies, tokens and authorization checks. This is the intended integration contract. Mounted development acceptance covers two synthetic clients. Real project registration, person assignment, product integration and complete logout acceptance remain required before rollout. Products do not share a session cookie or copy another project's access token. ## Current integration path The Go issuer remains restricted to isolated development with `AUTH_DEV_INSECURE_LOOPBACK=1` and a disposable loopback database. The portal uses its own confidential client, `taifa-identity-portal`; a separate mounted HTTPS acceptance exercises two synthetic clients, token audience isolation and central browser SSO. Reviewed installation of real project clients, person assignments, complete product logout and production acceptance remain gates. Use the [quick start](/docs/quickstart) for the local portal exercise and [platform status](/docs/platform-status) for the broader integration boundary. Management exposes a versioned API and reviewed workflows. Its current client delivery adapters and some portal paths still reflect the previous provider, so a reviewed management client record is not yet a Go issuer registration. The [client registration](/docs/client-registration) guide explains what a future application must provide. Taifa Identity is intended to be the central OIDC issuer. `OIDC_ISSUER` is the exact authority URL trusted by a consuming application; it can point to our own service. It does not require an external authentication provider. See [the OIDC reference](/docs/protocol) for the issuer settings and token validation rules. ## Identity rule Persist `(issuer, subject)` as the central identity key. Keep the product's own account ID. Map central Institution IDs to local tenant IDs explicitly. Email is a delivery and profile attribute; an email match never links accounts or restores access. Read the [identity mapping](/docs/identity-model) and [lifecycle](/docs/lifecycle) guides before protecting a route. --- # Quick start Run the owned issuer in an isolated local environment and test an OIDC authorization code flow. This exercise produces a synthetic account with no Institution or product roles. It cannot serve as a production application registration. > **Integration readiness:** This is an isolated development checkpoint. For application integration, start with [web sign-in](/docs/web), [native sign-in](/docs/native), and [client registration](/docs/client-registration). The runnable fixture below exercises only the existing local portal issuer; it does not create an approved product client or enable production sign-in. ## 1. Verify the local toolchain Start in the Taifa Identity repository root. Keep `TAIFA_IDENTITY_ROOT` in the same shell for the later command blocks. Use Go 1.27.1 and a disposable PostgreSQL database on loopback. The database name must include `test`, `scratch`, `dev`, or `preview`. The issuer refuses any other database in development. Set `AUTH_TEST_DATABASE_URL` to a disposable database URL for the database integration tests. Keep all secrets outside source control. ```sh TAIFA_IDENTITY_ROOT="$PWD" cd "$TAIFA_IDENTITY_ROOT/services/auth" go mod verify go vet ./... go test -race ./... go build ./... ``` The test suite uses `AUTH_TEST_DATABASE_URL` when provided. Database tests use unique disposable schemas. The tests cover PKCE, one-use codes, refresh rotation, expired authority leases, and challenge refusal. They do not require a live application client. ## 2. Create a disposable issuer Apply the numbered migrations from `services/auth/migrations/001_init.sql` through `014_owned_client_management_readback.sql` in order to that disposable database. Migrations 005 and 006 supply the registry, 007 supports enrollment, 008 supports logout, 009 supports durable activation retries, 010 supports private admission mail replay protection, and 011 supports central browser SSO. Migrations 012 and 013 add writer and custody schema foundations. Migration 014 scopes authenticated Management readback and its replay records; it does not register a client or grant access. Reviewed client installation remains unfinished, and this exercise does not enable the separate custody daemon. Holder setup is optional and requires separate signed authority configuration. This synthetic sign-in exercise does not provision a reviewed holder. Set these issuer variables through a private process environment: | Variable | Local value or purpose | | --- | --- | | `AUTH_DEV_INSECURE_LOOPBACK` | `1`; permits only the disposable loopback mode. | | `AUTH_CLIENT_REGISTRY_MODE` | `fixture`; allows only validated local fixture registrations in development. | | `AUTH_DATABASE_URL` | URL of the disposable PostgreSQL database on an explicit loopback IP. | | `AUTH_ISSUER` | Exact HTTPS issuer URL served by a trusted local TLS proxy. | | `AUTH_LOGIN_URL` | Portal's exact HTTPS `/signin` URL. | | `AUTH_CLIENT_REDIRECT_URL` | Portal's exact HTTPS `/auth/callback` URL. | | `AUTH_CLIENT_ID` | `taifa-identity-portal`. | | `AUTH_CLIENT_SECRET` | Independent random secret of at least 32 bytes, shared with the portal as `OIDC_CLIENT_SECRET`. | | `AUTH_BFF_KEY` | Independent random secret of at least 32 bytes, shared only with the portal BFF. | | `AUTH_PUBLIC_LISTEN`, `AUTH_INTERNAL_LISTEN` | Different explicit loopback IP listeners. Keep the internal listener private. | | `AUTH_TOTP_KEY_B64`, `AUTH_CRYPTO_KEY_B64` | Distinct standard Base64 encodings of independent 32-byte keys. | | `AUTH_SIGNING_KEY_FILE`, `AUTH_SIGNING_KEY_ID` | Owner-only RSA private key file, at least 3072 bits, and its public JWKS key ID. | Optional passkeys require all three of `AUTH_PASSKEY_RP_ID`, `AUTH_PASSKEY_ORIGIN`, and `AUTH_PASSKEY_KEY_B64`. The key must be a third independent 32-byte value. An authority lease receiver requires a separately reviewed subject mapping and the `AUTH_ELIGIBILITY_*` configuration in the service README; synthetic accounts do not use that receiver. ## 3. Register the disposable portal fixture In fixture mode, the current issuer validates local fixture registrations stored in `auth_clients`; environment variables alone do not register a client. This local-only fixture creates the portal registration with the SHA-256 digest of its private client secret and the exact configured callback. It refuses production databases and does not update an existing registration. Run it from `services/management`, whose locked environment supplies `psycopg`. These fixture registrations are not reviewed registrations, and migration 012's writer schema is not a runnable registration writer. ```sh cd "$TAIFA_IDENTITY_ROOT/services/management" uv run --locked python - <<'PY' import hashlib import ipaddress import os from urllib.parse import unquote, urlsplit import psycopg url = os.environ["AUTH_DATABASE_URL"] parsed = urlsplit(url) name = unquote(parsed.path.lstrip("/")).lower() try: loopback_host = ipaddress.ip_address(parsed.hostname).is_loopback except ValueError: loopback_host = False if (os.environ.get("AUTH_DEV_INSECURE_LOOPBACK") != "1" or not loopback_host or not any(word in name for word in ("test", "scratch", "dev", "preview"))): raise SystemExit("A disposable loopback database is required") secret = os.environ["AUTH_CLIENT_SECRET"].encode() if not 32 <= len(secret) <= 1024: raise SystemExit("An independent high-entropy client secret is required") with psycopg.connect(url) as connection: connection.execute( "INSERT INTO auth_clients " "(id,secret_hash,redirect_uris,resource_audiences,refresh_allowed," "management_access,review_id,enabled) " "VALUES (%s,%s,%s,%s,%s,%s,%s,%s) ON CONFLICT (id) DO NOTHING", ("taifa-identity-portal", hashlib.sha256(secret).digest(), [os.environ["AUTH_CLIENT_REDIRECT_URL"]], ["taifa-management"], True, True, "disposable-local-exercise", True), ) PY ``` Keep the fixture database and all secrets private. Startup rejects missing, disabled, malformed or mismatched portal registrations. The registration gives the synthetic person no management role. Start the issuer: ```sh cd "$TAIFA_IDENTITY_ROOT/services/auth" go run ./cmd/authd ``` A local TLS proxy may expose the configured HTTPS issuer while forwarding to the loopback public listener. Do not expose the private challenge listener. The issuer publishes discovery, `/authorize`, `/oauth/token`, and `/keys`; the browser challenge API is private to the portal BFF. ## 4. Create one synthetic account Set `AUTH_BOOTSTRAP_USERNAME` and `AUTH_BOOTSTRAP_OUTPUT` to a path in a private `0700` directory. With the same disposable database and TOTP encryption key, run: ```sh cd "$TAIFA_IDENTITY_ROOT/services/auth" go run ./cmd/auth-bootstrap ``` The output file is `0600` and contains the generated subject, password, and TOTP seed. Use it only for the local exercise. The account's lease lasts one hour and it has no management privilege. ## 5. Exercise the browser flow Apply `apps/portal/migrations/001_sessions.sql` to a separate disposable portal database, or set `PORTAL_DATABASE_URL` and run `npm run migrate` from `apps/portal`. Install the locked portal dependencies with `npm ci`. The portal needs `PORTAL_ORIGIN` (trusted HTTPS origin), `PORTAL_DATABASE_URL`, `PORTAL_SESSION_KEY` (standard Base64 encoding of exactly 32 cryptographically random bytes), `OIDC_ISSUER` (equal to `AUTH_ISSUER`), `OIDC_CLIENT_ID=taifa-identity-portal`, `OIDC_CLIENT_SECRET` (equal to `AUTH_CLIENT_SECRET`), `AUTH_ISSUER_URL` (equal to `OIDC_ISSUER`), `AUTH_INTERNAL_URL` (the private issuer listener), `AUTH_BFF_KEY`, `AUTH_ENGINE_MODE=custom`, and `AUTH_DEV_INSECURE_LOOPBACK=1`. Trust the local TLS certificate in the browser and backend. Keep the private listener off public ingress. ```sh cd "$TAIFA_IDENTITY_ROOT/apps/portal" npm ci npm run migrate npm run check npm run build npm run dev ``` Serve the portal development process through the trusted HTTPS origin named by `PORTAL_ORIGIN`, then begin at `PORTAL_ORIGIN/auth/login`. The BFF maintains the login transaction, an HttpOnly challenge cookie, and CSRF protection. Password plus TOTP or a configured passkey completes the private challenge. The browser follows the issuer callback URL, and the BFF redeems the code with the original S256 verifier. Inspect the resulting verified `iss` and `sub` in the session and the account screen. The synthetic subject has no product access or management roles; protected account screens may refuse it. Requesting `offline_access` with the initial scope permits refresh token issuance; refresh tokens rotate within the original eight-hour session. An ID token is never a management API token. For an application-shaped code sample, run the injected protocol tests in `examples/node`, `examples/fastapi`, or `examples/native`. Those examples need a separately approved client before a real provider sign-in. ## Next step Read [client registration](/docs/client-registration) for the remaining multi-client gate, then [web sign-in](/docs/web) or [native sign-in](/docs/native). Do not route a product's workforce traffic to the disposable portal client. --- # Platform status Use this page to choose a safe starting point. A source implementation or API contract is not a deployed production service. | Capability | State | What you can do now | | --- | --- | --- | | Go OIDC issuer with authorization code, PKCE S256, RS256 keys, password plus TOTP, optional passkeys, refresh rotation | Isolated development | Run isolated issuer tests and the HTTPS two-client synthetic browser acceptance. | | Separate custom Svelte authentication UI and portal login transactions | Development | Exercise password/TOTP, resident virtual passkeys, silent two-client SSO and native forms with JavaScript disabled. | | Python management API, governance, audited mutations, lifecycle feed and snapshots | Implemented contract | Inspect the generated schema and run service tests. Deployment and authority configuration still require review. | | Signed workforce lease receiver | Isolated integration | Verify a reviewed subject mapping against the private publisher. Synthetic bootstrap accounts cannot receive workforce authority. | | Reviewed enrollment, service identity and Mail delivery workflows | Management boundary | Review the API contract and scoped source tests; genuine holder and product acceptance remain separate. | | Registry-backed confidential web clients | Isolated integration | Test two client policies, exact callbacks, audiences, revocation and refresh isolation. Reviewed provisioning remains a gate. | | Private holder setup API, custom `/setup` UI, server-owned password/TOTP enrollment, signed cancellation and durable activation retries | Development wiring | Test bound setup and isolated recovery. The invitation/Mail bridge is implemented. Real reviewed holder acceptance, effective product delivery and privileged passkey enrollment remain gates. | | Central browser SSO | Mounted development acceptance | Two synthetic confidential clients redeem verified tokens with separate audiences/cookies and one central SID. Real project assignments and product rollout remain gated. | | Independent catalog and owned-client policy review | Management boundary | Propose and review immutable client/catalog revisions. Client approval waits for a separately verified registration readback; it does not enable sign-in. | | Owned-client credential delivery tool and private custody receiver | Qualified Linux handoff | Focused tests cover protected files, signed intent/receipt validation, verified TLS, PostgreSQL persistence and acknowledgement. Current-owner intent creation, connected Management delivery and reviewed registration installation remain gates. See [credentials and rotation](/docs/credentials). | | Independent exact Access-version and grant-Event review | Management boundary | An actual Sponsor and a different effective administrator record immutable decisions. Current grant facts and product Event acknowledgment are separate GET fields; signed issuer assignment remains a gate. | | Full logout, production admission, recovery and signing-key rotation | Release gate | Complete real product, strong-authentication and operational acceptance before rollout. | ## What this means for applications The portal BFF remains explicitly configured as `taifa-identity-portal`; the issuer resolves client policy through its reviewed registry. Web and native examples in this repository show standards-based integration patterns and have injected tests, but they are not registered against the owned issuer. The mounted development runner separately registers two synthetic confidential clients and verifies the actual Go/UI/HTTPS flow. A product must wait for reviewed client provisioning, independently approved person assignments and a production issuer before enabling mandatory sign-in. The management service still contains legacy provider delivery paths while the owned engine is being built. They are migration and rollback artifacts, not the target platform. Public examples here describe the owned-engine contract and clearly label what cannot yet be executed against it. ## Release checks Before a real deployment, validate reviewed provisioning and initial privileged admission, recovery, multi-client SSO, logout and back-channel revocation, key rotation, PostgreSQL 16, migrations and restore, ingress isolation, edge rate limits, real authenticators, product lifecycle catch-up, and an end-to-end Mail journey. Record measured acceptance in private release evidence. The [deployment](/docs/deployment) and [migration](/docs/migration) guides describe the work an operator must complete. --- # Projects and approval A project identifies the product that will consume Identity. Create a named owner and request each environment separately. Approval of a management project does not automatically register an OIDC client with the owned Go issuer. ## Prepare a request Decide whether the application is a confidential web backend or a public native app. Record its owner, purpose, exact callback URLs, requested scopes, environment, and the local Institution mapping it will use. Keep staging and production credentials separate. A web callback uses HTTPS outside disposable loopback development. Native callbacks must match the reviewed platform profile exactly. Wildcards and anonymous dynamic registration are not supported by the reviewed management flow. Project owners can inspect `GET /v1/projects/{project_id}/registration-context` and `GET /v1/projects/{project_id}/environments` with an authorized management token. `GET /v1/registration-context` reports the configured environment and issuer. A missing or inconsistent deployment binding returns 503. These responses describe the management deployment currently serving the request, so verify they match your intended issuer before proposing or approving a client. ## Owned project-client review An approved project is the context for a separately reviewed permission catalog and exact owned-client policy. The project owner proposes each immutable revision, and a different current project approver reviews it. The project detail page shows the exact client version, URI/audience policy, catalog permissions and registration digest. Client approval remains `approved_pending_readback`; the reviewed private registration writer must later prove the exact Go installation before it becomes usable. See [register a client](/docs/client-registration). Person access is another decision. Independently reviewed sponsor and administrator authority must bind the exact beneficiary and Access version, and neither reviewer may be the beneficiary. Product acknowledgement is required in addition to those reviews. A project, catalog or client approval does not itself grant a person access. ## Inspect current authority Open the project admin page to inspect its lifecycle acknowledgement and reviewed client authority observations. The same bounded read is available through `GET /v1/projects/{project_id}/authority-status`, using a backend-held Management access token. It is scoped to the current project owner or authorized project approver and exposes no credentials or private signed artifacts. Check each fact separately. A recorded source acknowledgement is historical; a source grant can expire; an activation request is an intent. None proves that Go activated the registration or that a person can sign in. An unavailable status view means the facts could not be confirmed. Restore the Management connection and reread the status before making an access decision. ## Legacy environment review sequence 1. An authorized owner proposes an environment at `POST /v1/projects/{project_id}/environments` with a unique `Idempotency-Key`, a reason, exact callbacks, and scopes. A confidential web proposal body has this shape: ```json {"name":"staging","client_type":"confidential-web","redirect_uris":["https://app.example.test/callback"],"scopes":["openid","profile"],"reason":"Initial staging integration review"} ``` The API also accepts `development`, `production`, `public`, and the fixed native Mail client types, subject to deployment policy. Web scopes here are `openid`, `profile`, and `email`; `openid` is required. The Go issuer's refresh-token `offline_access` behavior does not yet make it an approved management registration scope. 2. A different live project approver checks the proposal and approves it through the environment approval route. 3. The worker reconciles external delivery. A `pending` or `approved` record does not prove the client is usable. Confirm the effective state and exact issuer binding. 4. For a confidential client, the authorized owner uses the one-time credential reveal flow. Store the secret in a server-side secret manager. Rotation is a separate reviewed action. The current worker delivery path is part of the legacy migration boundary. The owned issuer now exercises two distinct synthetic confidential registrations in its mounted browser acceptance. That test does not convert a legacy environment approval into a reviewed owned-client registration. Use the separate owned policy review and later signed readback gates. ## Verify before traffic Check OIDC discovery at the approved issuer, exact redirect matching, PKCE S256, token audience, and the product's lifecycle service identity. Do not use a staging client or issuer for production. See [register a client](/docs/client-registration) for the profile details. --- # Register a client Every application needs its own reviewed OIDC client. The owned Go issuer enforces versioned confidential web client registrations stored in PostgreSQL. Exact HTTPS callbacks, permitted audiences, refresh policy, enabled state and registration version constrain code issuance, exchange, refresh, UserInfo and introspection. Disposable PostgreSQL tests exercise two clients and cross-client refusals. The mounted custom UI has passed two-client browser SSO with synthetic registrations. Real reviewed registration writing, exact person-to-project assignment and full product logout remain release gates. An approved policy does not yet install a usable client. ## Choose a profile ### Web backend Register the exact HTTPS callback, client ID, confidential secret, and logout endpoint where supported. The backend exchanges a code with PKCE S256 and stores the product session. ### Native mobile or desktop Register the exact app link or approved loopback redirect and a public client ID, with no secret. The system browser handles authorization; the app uses PKCE S256. ### Lifecycle consumer Use a reviewed project-scoped service identity and management audience. The server polls the signed lifecycle feed; this identity is separate from the browser client. A native Mail client uses a fixed reviewed callback profile. The generic `examples/native` loopback reference is not a Mail client registration. The current Go issuer does not implement arbitrary native or machine client issuance. ## Review the owned client policy 1. Use the [project review](/docs/projects) flow to establish an approved project and current owner. In the project detail page, propose a permission catalog with exact IDs and descriptions. A separate current project approver reviews that immutable revision. OIDC scopes such as `openid` are protocol inputs, not those product permissions. 2. Complete credential custody before the client-policy review. The current owner requests a short-lived [credential intent](/docs/credentials), and the operator-controlled tool delivers the credential to the configured owner runtime. The browser receives only a pending intent ID. After handoff, the operator exports a protected proof containing the preparation reference. This development boundary does not install the client. 3. Propose the owned-client policy against the approved catalog. It binds the exact owned issuer, client ID and version, callback/logout URI sets, resource audiences, refresh policy, nonsecret credential fingerprint and selected reviewed permission IDs. The server assigns the policy review reference and computes a canonical registration digest. A separate policy digest binds the project, permission catalog, selected permissions, display name and generation. Owners cannot submit or invent the review reference. 4. Have an independent approver inspect the actual policy and both exact digests. Changing the policy requires another revision. The public [reviewed project-client API group](/docs/api/groups/reviewed-project-clients) provides list, proposal, approval and revocation operations. Every mutation requires a unique `Idempotency-Key`, an audit reason and current scoped authority. Keep the same key and exact body after an uncertain response. Reusing a key with changed content returns 409. See [the Management API](/docs/management-api) for authentication and idempotency. ## Attach the preparation reference The development proposal API requires `credential_preparation_id` alongside `catalog_id` and `registration`. Use the canonical lowercase UUID from the controlled delivery proof. The intent ID is a different identifier. Do not submit the secret, a signed receipt, a browser-calculated custody digest or a filesystem path. Management obtains a fresh signed observation directly from the configured private issuer endpoint before starting the policy transaction. It verifies the exact project, issuer, client ID and version, current owner, credential fingerprint and original handoff deadline. Proposal and independent approval each require their own current observation. A retained proof is a reference for this check, not authority to skip it. Successful client responses include `credential_preparation_id` and the server-verified `custody_binding_digest`. Both are nonsecret correlation fields. Historical records may return `null`; they cannot acquire accepted custody evidence merely by being read or retried. The proposal also binds the exact independently approved permission catalog and current owner authority. Approval requires a different current authorized reviewer and recent strong authentication. This attachment implementation is undergoing combined qualification. Reviewed installation, effective client readback and production activation remain separate release gates. ## Read the review state The project admin page also reads `GET /v1/projects/{project_id}/authority-status`. Current project owners and authorized project approvers can inspect the separate review, lifecycle acknowledgement, source grant and activation observations. Management cannot confirm issuer activation from an approval or an activation request. Treat an unknown, pending or expired observation as incomplete, and verify the deployed API version before using this route. - `pending_review`: The proposed revision has no accepted independent approval. - Catalog `approved`: The reviewed permission catalog may be used in a client-policy proposal. - Client `approved_pending_readback`: The exact policy is approved, but a separate signed Go registration readback is still required. Sign-in is not enabled by this state. - `superseded` or `revoked`: Historical evidence remains available. The revision cannot supply current authority. The current API does not provide an effective client state or install a registration. Credential custody readback verifies handoff; registration readback must separately verify an installed client. The installation writer and assignment publisher remain implementation gates. A person also needs an independent sponsor/administrator review tied to their exact Access ID and version, plus effective product acknowledgement. A direct single-admin grant, a historical request or client approval alone cannot qualify them. Management's `/v1/registration-context` reports `provider: owned` and `client_registration_enabled: false` in a valid owned deployment. That flag controls the retained legacy environment-registration forms. It does not disable the owned-client proposal and review API described here, and it does not imply that an approved owned policy can already sign in. Do not mix these reviews with legacy environment provisioning. Existing `ProjectEnvironment` and credential-reveal routes serve migration and rollback. Native and machine profiles have their own contracts and are not implied by the owned confidential-web proposal API. ## Handle expiry and configuration Pending reviews expire after 90 days. A replacement proposal supersedes expired evidence in the same audited transaction. A never-approved proposal may reuse its client version with a new generation and server-assigned review reference. After an approved proposal, a missing readback could represent a lost installation response, so a replacement requires a higher client version. The platform operator sets `AUTH_ENGINE_TARGET_ISSUER` to the exact reviewed owned issuer. It is independent of the issuer trusted for current Management human tokens. The settings may coincide after an approved owned-workforce migration, but one is never inferred from the other. The privileged portal client ID and management audience remain reserved to the configured portal project; every other product gets a separate client and product audience. Missing or inconsistent authority configuration returns 503. - `403`: Check current scoped authority, independent reviewer and authentication assurance. - `409`: Re-read the exact catalog and policy. Resolve a changed owner, version, preparation binding or idempotency conflict before proposing again. - `413`: Keep the complete JSON request within 64 KiB. - `422`: Use the typed request schema, a canonical preparation UUID and JSON without duplicate fields. - `503`: The operator must restore the configured authority or private custody verification service. Do not replace verification with browser proof. ## Record the result Store the exact issuer URL, client ID, callback, allowed scopes, and credentials in deployment configuration. A confidential secret stays on the backend. Native apps cannot keep a client secret. The application should discover endpoints from `ISSUER/.well-known/openid-configuration`, validate ID tokens for its own client audience, and use a separate access token for management or product APIs. Do not reuse `taifa-identity-portal` for another application. See [web sign-in](/docs/web) and [native sign-in](/docs/native) for implementation patterns. --- # Web sign-in A web product should complete OIDC authorization code with PKCE S256 in its backend and give the browser only a product session cookie. The repository's Node.js and FastAPI examples demonstrate this pattern with injected tests. The owned issuer resolves multiple confidential registrations, and mounted HTTPS acceptance exercises two synthetic apps with separate sessions and verified audiences. Reviewed installation of real product clients remains gated on the registration writer and signed readback. The Node runtime also requires an approved lifecycle consumer; its tests use injected dependencies and run without a live issuer. ## Configure the backend Obtain a separately reviewed confidential client with an exact HTTPS callback and client secret. Configure the exact issuer, client ID, secret, application origin, and a server-side session store. Use a maintained OIDC library and discovery. Never construct authorization or token URLs by guessing paths from an earlier deployment. ```sh cd examples/node npm ci npm test ``` For a live run after multi-client registration, set these runtime variables from the approved registration and private deployment configuration: | Variable | Value | | --- | --- | | `OIDC_ISSUER`, `OIDC_CLIENT_ID`, `OIDC_CLIENT_SECRET` | Exact HTTPS issuer and confidential client credentials. | | `APP_ORIGIN`, `PORT` | Trusted HTTPS origin and loopback server port, default 8002. Register `APP_ORIGIN/callback` and `APP_ORIGIN/backchannel-logout`. | | `PROJECT_ID`, `LIFECYCLE_URL` | Approved project ID and exact HTTPS `/v1/lifecycle/{project_id}` URL. | | `LIFECYCLE_SERVICE_TOKEN`, `LIFECYCLE_PUBLIC_KEY_FILE` | Short-lived project-scoped service token and dedicated lifecycle verification key file. | ```sh cd examples/node npm start ``` Open `APP_ORIGIN/login` through trusted HTTPS ingress. The Node reference sends `openid profile` with state, nonce and PKCE S256 and verifies the returned ID token. After login, `GET /` returns a shape like this, using the actual issuer and subject rather than these illustrative values: ```json {"identity":{"issuer":"https://issuer.example.test","subject":"SUBJECT_FROM_ID_TOKEN"},"product_access":"not granted by OIDC"} ``` The protected `/workforce` route checks lifecycle state, then returns 403 until a product-specific role adapter is supplied. Example sessions and lifecycle state are in memory, so they must be replaced before a real deployment. ## Python backend alternative `examples/fastapi` uses Authlib and a signed, `Secure`, `HttpOnly` session cookie. Set `OIDC_ISSUER`, `OIDC_CLIENT_ID`, `OIDC_CLIENT_SECRET`, `APP_ORIGIN`, and `SESSION_SECRET` (at least 32 random characters) in a private runtime environment. Register the exact `APP_ORIGIN/callback` URL, then run: ```sh cd examples/fastapi uv sync --locked uv run pytest -q uv run uvicorn app:build_app --factory --host 127.0.0.1 --port 8001 ``` Serve the loopback process through trusted HTTPS at `APP_ORIGIN`. Open `APP_ORIGIN/login`. Its `/` response contains `identity.issuer`, `identity.subject`, and `product_access: not granted by this example`; it does not implement lifecycle or product roles. ## Complete the callback Bind each authorization attempt to a server-side transaction. Compare the returned state, redeem the code once using the original verifier, validate nonce and the signed ID token's issuer, audience, expiry, and subject. Create a local product session keyed to `(iss, sub)` only after mapping it to an existing authorized local account. Store the browser session in a `Secure`, `HttpOnly`, `SameSite` cookie. Keep access and refresh tokens out of browser storage. ## Protect a route Check the product's local role and Institution mapping, then the latest signed lifecycle projection. A successful central login alone is insufficient. On a revoked event or expired freshness, stop protected access and revoke local sessions and real-time connections. The Node example deliberately refuses product access until this adapter exists. ## End a session Local `POST /logout` must check origin or CSRF and clear the product session. The example also validates OIDC back-channel logout tokens for signature, issuer, audience, event, session ID, issue time, and replay ID. The Go issuer has an exact-session logout adapter and durable signed fanout implementation. Complete browser logout, real product delivery/acknowledgement and late-session refusal remain release gates. Test the complete path against your approved issuer and product before rollout. --- # Native sign-in Use the operating system browser for authorization code with PKCE S256. A native client is public: it has a client ID and exact registered callback, but no client secret. Never embed a central password form or use email to select a local officer account. ## Run the reference tests The generic desktop reference binds an ephemeral listener on `127.0.0.1`, opens the system browser, checks state before exchange, and validates nonce and the ID token through `openid-client`. It prints only issuer and subject. It neither creates a product role nor requests a management API token. ```sh cd examples/native npm ci npm test ``` A live run needs only `OIDC_ISSUER` and `OIDC_CLIENT_ID` in its runtime environment. The issuer must be trusted HTTPS, and that reviewed public client must permit `http://127.0.0.1:{ephemeral-port}/callback` under its native redirect policy. The owned issuer has no such client today. Once one exists, run: ```sh cd examples/native npm start ``` A successful run prints a JSON object shaped like this, with the actual issuer and subject: ```json {"identity":{"issuer":"https://issuer.example.test","subject":"SUBJECT_FROM_ID_TOKEN"},"product_access":"requires separate local authorization"} ``` The fixed Mail mobile and desktop profiles use different exact callbacks, so they cannot run this generic loopback reference as-is. ## Build a product client Bind the callback listener before launching the browser. Generate a fresh state, nonce and S256 verifier for each attempt. Match the callback to the exact request, redeem the code once, and validate the signed ID token for issuer and client audience. Store any retained tokens in platform secure storage. Send an access token to a backend only when it is issued for that backend's audience and scope. The backend maps `(iss, sub)` to an existing local account, checks current product eligibility, Institution and role, then creates its own session. A native app should refresh or reauthenticate when that local session is revoked. For Mail-specific audience and callbacks, see [Taifa Mail](/docs/mail). --- # OIDC reference The owned Go service implements an OIDC authorization-code issuer. Its registry resolves confidential web clients, and mounted development acceptance covers two synthetic clients. Configure a maintained OIDC library from the exact issuer's discovery document. An application must not assume that a client approved in management is already registered with this issuer. ## What the issuer means `OIDC_ISSUER` tells an application which authentication authority to trust. Taifa Identity is intended to be that authority for Taifa AI, Mail, Support, Sign and future projects. Its Go service uses `AUTH_ISSUER` for the same exact server identity. Products redirect people to its custom sign-in UI and verify the returned signed identity against its public keys. A central session allows another registered project to sign in without repeating the login ceremony, subject to that project's current access policy and assurance requirements. The issuer URL must match discovery metadata and the token's `iss` exactly. A hostname, origin or path change creates a different issuer identity; it does not automatically carry existing account authority across. The owned issuer remains restricted to isolated development while production acceptance is incomplete. | Setting | Configured service | Meaning | | --- | --- | --- | | `AUTH_ISSUER` | Go authentication engine | Its own exact issuer URL, used in discovery and signed tokens. | | `OIDC_ISSUER` | Portal, Management API or integrating product | The exact issuer that service trusts for sign-in or token verification. | | `OIDC_JWKS_URL` | Management API | The explicitly configured URL of the trusted issuer's public verification keys. This is not a private signing key. | | `AUTH_ENGINE_TARGET_ISSUER` | Management client-policy review | The owned issuer for which a client policy is being reviewed. It is not inferred from the current human-token issuer. | After a reviewed workforce migration, the trusted human issuer and owned target may coincide. Changing configuration alone does not migrate existing `(issuer, subject)` bindings, register clients or grant authority. Configure each service deliberately, retain the exact identity mappings, and complete [migration acceptance](/docs/migration) before switching production traffic. ## Discover endpoints Read `ISSUER/.well-known/openid-configuration`. The local public handler exposes discovery, `/authorize`, `/oauth/token`, and `/keys`. Treat the discovery response as the endpoint source. The issuer signs RS256 tokens with a configured key ID and publishes the verification key. Pin the expected issuer in your deployment configuration and reject an unexpected discovery issuer. ## Request a code Use `response_type=code`, `scope=openid profile` as needed, a fresh state and nonce, an exact registered redirect, and `code_challenge_method=S256`. Store the matching verifier in the backend or platform-secure native transaction. Products use the public OIDC flow; they do not collect a central password or call private factor APIs. In central browser SSO mode, the separate authentication UI runs at the issuer origin. Its backend calls the private central authentication API with a dedicated service credential and server-held flow capabilities. Each request has its own durable browser and CSRF binding. The product portal retains its own login transaction and callback; it does not supply the central UI's cookie or factor state. The earlier single-portal development exercise uses the portal BFF's private challenge adapter instead, with its separate bearer key and `X-Taifa-Auth-State` binding. That flow remains the explicitly scoped [quick start](/docs/quickstart). Neither private adapter is a public product integration API. The current issuer supports `openid`, `profile`, `email`, and `offline_access`. Include `offline_access` in the original request to obtain a rotating refresh token. A refresh token cannot extend beyond the original eight-hour session. Do not assume support for implicit flow, password grant, dynamic registration, or client credentials. ## Validate the response A library must verify the signature, `iss`, client `aud`, expiry, nonce, and subject. Match the callback state before token exchange. The ID token identifies the signed-in person for the client. It is not an access token for the management API or a product API. For management, use an access token with audience `taifa-management` and current authorization. The issuer may set `acr=taifa-mfa` after password plus TOTP, or `acr=taifa-phishing-resistant` after a user-verified passkey. A requested assurance value is not evidence; inspect the verified token and current session. Platform administrator operations and catalog/client-policy proposals and approvals require the phishing-resistant value and an actual recent `auth_time`. Check the specific API operation's authorization contract before presenting a review action. ## Identifier stability `sub` is the immutable account identifier within one issuer. The exact `(iss, sub)` pair is the durable key across products. Login names and email can change. The development service currently matches login identifiers exactly and rejects case-colliding reservations, while the final admission policy is still pending. Do not derive identity from username or email. --- # API authentication The Python management API accepts a bearer access token with the configured issuer and exact audience `taifa-management`. It verifies RS256 signature, key ID through JWKS, `exp`, `iat`, `sub`, `iss`, and `aud`. Routes then check current local eligibility and scoped roles. A successful OIDC login does not grant management access by itself. ## Send a request Use an approved private management URL and a short-lived access token issued for this API. Keep the token in backend memory or a protected server store. The portal BFF already uses backend-held tokens for personal routes. Do not put a management token in public JavaScript, a URL, or a command checked into source control. ```http GET /v1/me HTTP/1.1 Authorization: Bearer ACCESS_TOKEN_WITH_TAIFA_MANAGEMENT_AUDIENCE Accept: application/json ``` `GET /v1/me` returns the current Person ID, issuer, subject, version, roles, memberships, and project access visible to that person. Its success response has a declared model in the generated [management API reference](/docs/management-api). Some other operations still have unspecified success shapes in OpenAPI. The bearer security scheme does not encode every role or eligibility rule; endpoint-specific authorization is enforced separately by management. ## Mutation authorization Human mutations require a current authorized person, an actual strong login no more than 300 seconds old, a JSON `reason` of 8 to 500 characters, and a unique `Idempotency-Key` header of at most 200 characters. Platform administration requires phishing-resistant assurance. The server rechecks current sponsorship, Institution scope, and independent review at the transaction boundary. Replaying the same key and body returns the stored response; reusing a key for different input returns 409. ```http POST /v1/projects/PROJECT_ID/environments HTTP/1.1 Authorization: Bearer ACCESS_TOKEN_WITH_TAIFA_MANAGEMENT_AUDIENCE Idempotency-Key: YOUR_UNIQUE_REQUEST_ID Content-Type: application/json ``` The body depends on the operation; inspect its schema before sending. Do not substitute an ID token. Machine routes use their own reviewed service identity and request contract. ## Interpret refusal A missing or invalid bearer token yields an authentication failure, an unauthorized role or Institution yields 403, invalid input may yield 422, a stale or conflicting state often yields 409, and unavailable signing or audit dependencies yield 503. FastAPI responses generally contain a `detail` field, while validation failures contain structured `detail` entries. The response includes `X-Request-ID` for support correlation. Never record a full token or credential in diagnostics. --- # Machine access Background lifecycle polling and product attestations need a service identity separate from a person's browser login. Management validates machine access tokens for `taifa-management`, exact roles, and a project ID, then checks a reviewed service record where the operation requires one. The owned Go issuer does not yet issue general client-credentials tokens, so this is an integration contract, not a runnable token-minting recipe. ## Lifecycle consumer Give one product a dedicated service identity with the `lifecycle-consumer` management role and its approved `project_id`. Call `GET /v1/lifecycle/{project_id}?after=CURSOR` with a renewed access token. The API refuses a token whose project claim does not match the path or whose project is not approved. Verify each signed event and receipt with the dedicated lifecycle key, not the OIDC signing key. Poll every 15 seconds and keep the cursor durably with the applied product changes. See [eligibility and lifecycle](/docs/lifecycle). ## Account-link attestor A product that proves an existing local account needs an independently reviewed service identity with the `account-link-attestor` capability for that exact project. The service must attest fresh local and central proof to the scoped account-link API. A role claim alone does not authorize it; management checks the approved issuer, subject, project, capability and current service state. The product must acknowledge the exact installed binding after its transaction commits. Read [identity and account mapping](/docs/identity-model). ## Credential handling Keep machine credentials in a server-side secret manager and rotate them separately from browser client secrets and OIDC signing keys. Use separate identities per product and environment. Plan token renewal and revocation; do not paste a human access token into a daemon configuration. Provisioning and token issuance for these clients remain part of the owned-engine multi-client release gate. Internal issuer-to-management admission and authority lease calls use dedicated private HMAC and signing keys. They are not public OAuth client credentials and are not available to product applications. --- # Management API The Python service publishes versioned `/v1` routes for people, Institutions, projects, approval workflows, lifecycle, audit, and operations. The generated OpenAPI document below reflects the routes and request schemas published by this source version. Success response models are declared for own account and freshness; core Institution, person, project, membership and access reads; audit reads and search; the operations summary; lifecycle feed, snapshot and acknowledgement; project catalog and client review; exact Access grant review; and reviewed lifecycle service grants. Other success shapes remain unspecified. The service URL is private deployment configuration, not a universal public API hostname. ## Find the route you need - **Read own account and freshness:** `GET /v1/me`, `/v1/me/freshness`. Returns an account object, or signed snapshot and receipt. - **Review Institutions and projects:** `GET /v1/institutions`, `/v1/projects`. Returns arrays scoped to current authorization. - **Inspect project authority:** `GET /v1/projects/{project_id}/authority-status`. Returns bounded source observations for lifecycle acknowledgement, reviewed clients, source grants and activation. A current signed readback may report the Go writer's observed active state until an exclusive deadline. It does not confirm effective sign-in. - **Request a client environment:** `/v1/projects/{project_id}/environments`. Returns reviewed workflow records. - **Review catalog and owned-client policy:** `/v1/projects/{project_id}/permission-catalogs`, `/owned-clients`. Returns exact independently reviewed metadata; client approval awaits installation readback. - **Request controlled credential custody:** `POST /v1/projects/{project_id}/owned-clients/credential-intents`. Returns an intent UUID and `custody_status: pending`; no secret, installation or effectiveness claim. - **Independently review an Access version:** `/v1/institutions/{institution_id}/access-grant-reviews`. Returns candidates, immutable decision receipts and separate current/delivery facts. - **Consume product eligibility:** `/v1/lifecycle/{project_id}` and `/snapshot`. Returns signed events or snapshot, receipt, cursor. - **Search audit:** `GET /v1/audit/search`. Returns `items`, `next_cursor`, `limit`. - **Diagnose delivery:** `GET /v1/operations/diagnostics`, project diagnostics. Returns queue and acknowledgement state. The simple `GET /v1/audit` endpoint returns up to 200 entries. Use `/v1/audit/search` for filtered cursor pagination: its `limit` is 1 to 1000, default 100. Pass back the returned `next_cursor` with the same actor, scope and filters. An invalid cursor returns 400. ## Authenticate and mutate Use a bearer access token with audience `taifa-management`. Most protected reads additionally require current local eligibility. For human mutations, send a new `Idempotency-Key` and an operation-specific JSON body containing an audit `reason` of 8 to 500 characters. Actual strong authentication must be recent; platform administration needs phishing-resistant assurance. The server commits the mutation, audit record, idempotency response, and outbox work together. A queued result is not product effectiveness. ## Follow completion Some approved actions require worker delivery or exact product acknowledgement. Distinguish `pending`, `accepted`, and `effective`; do not promise access based on an approval response. Lifecycle acknowledgements report the applied sequence. Account linking has an additional exact binding acknowledgement. See [lifecycle](/docs/lifecycle) and [operations](/docs/operations). Exact grant-review POSTs return immutable decision receipts. Current validity and event acknowledgment are available from the scoped GET, including after an exact idempotency replay. `pending_review` intentionally reports `current:false`. An approved review or client policy does not establish an installed client or effective issuer assignment. [Review the typed grant API](/docs/api/groups/reviewed-access-grants) and reread current facts after every uncertain decision. Credential intents expire at their original deadline, at most 120 seconds after creation. An exact replay cannot renew an intent or restore revoked authority. The controlled runtime obtains the signed intent through a separate private machine boundary; that operation is excluded from the public API reference. See [credentials and rotation](/docs/credentials) for the human request and custody rules. Reviewed client installation and production activation remain separate requirements. ## Read project authority observations Use the [project authority status operation](/docs/api/operations/project_authority_status) to inspect one approved project with current owner or project-approver authority. This read requires a Management access token. It does not create or approve authority, and it does not require an idempotency key or a mutation reason. ```http GET /v1/projects/PROJECT_ID/authority-status?limit=25&offset=0 HTTP/1.1 Authorization: Bearer ACCESS_TOKEN_WITH_TAIFA_MANAGEMENT_AUDIENCE Accept: application/json ``` The response separates `lifecycle`, client `policy`, `stream`, historical `source_ack`, source `grant` and `activation` observations. Lifecycle sequences, client versions and generations are decimal strings, preserving the full integer value in JavaScript. Observation and expiry timestamps use Unix seconds. The top-level `activation_effectiveness` remains `unknown`. Each activation's `effectiveness` is `unknown` unless Management has verified the exact historical activation result and a fresh signed positive Go readback against the current source grant and review chain. A positive value is `observed_active` only until its exclusive `observed_active_until` timestamp. The original activation `expires_at` is historical and can precede a later renewal observation. A loaded view downgrades the positive display at the deadline; reload the route to detect a source decision or custody change. This writer-local observation does not establish issuer sign-in effectiveness or production release. An unexpired source record, historical ACK or pending activation alone must not enable sign-in or product access. Collection reads accept `limit` from 1 to 50 (default 25) and `offset` from 0 to 10000. Follow a non-null `next_offset` to read another page. Each request observes the current source records; pages are not a frozen snapshot. Reread after a review, revocation or renewal changes the collection. The endpoint does not return credentials, machine nonces, private signed payloads or beneficiary identities. If a next page would exceed the offset bound, the route returns 409 with `detail: "pagination_limit_reached"`. It does not report the truncated list as complete. Handle that refusal explicitly rather than treating it as an empty page. If the route returns 403, check the current project scope rather than trusting an old role claim. A 404 means an approved project was not available. Handle an unavailable response as an unconfirmed observation, not a clean or effective state. Verify the deployed API version before using this source addition. ## Errors and versioning Error responses use FastAPI's `detail` shape, with `X-Request-ID` on responses. A 409 can mean changed state or an idempotency conflict. A 503 can mean required authentication, audit, signing, or delivery dependencies are unavailable. Handle unknown optional fields and read the downloadable OpenAPI JSON at `/docs/openapi.json` for the deployed source version. Verify the actual deployed API version separately before using a newly documented route. ## Browse the reference [Open the API reference](/docs/api) to browse resources, operation pages, declared request and response fields, and cURL, TypeScript, and Python request examples. [Download the public OpenAPI JSON](/docs/openapi.json) for the exact published source contract. Undocumented success shapes are labeled explicitly. ## Lifecycle service grants The source exposes `/v1/projects/{project_id}/lifecycle-service-grants` for three decisions: 1. A current owner proposes a grant with `issuer`, `subject`, and `reason`. 2. An independent platform reviewer approves it at `/{grant_id}/approve` with `expected_version`, `proposal_digest`, and `reason`. 3. A current scoped owner or platform reviewer terminally revokes it at `/{grant_id}/revoke` with the current `expected_version` and `reason`. Human decisions require `Idempotency-Key` and a trimmed 8..500-character reason. GET returns scoped grant metadata and accepted Audit references, never credentials. Collection reads use `limit` (1..100, default 50) and optional `after_id`. Pending review is version 1; local effective authority is version 2. Revocation increments the version and cannot reactivate. Attestor grants do not authorize feed, snapshot or ACK, and machine requests require exactly the lifecycle role plus current exact-purpose grant. Grant approval is neither token issuance nor client installation. Owned issuer client-credentials issuance remains unimplemented; verify the deployed API before using newly documented routes. --- # Identity and account mapping Store a central identity as the exact `(issuer, subject)` pair. Keep your own immutable local account ID and an explicit central Institution-to-local tenant mapping. Email, username, and display name are attributes, not linking keys. This rule prevents two people with the same address from sharing access and preserves an account through an email change. ## Map a successful login 1. Validate the signed OIDC ID token for your client, issuer, audience, nonce and time bounds. 2. Look up the existing local link by `(iss, sub)` in the product's durable account table. 3. Check that the linked account still belongs to the selected local tenant and has the required product role. 4. Check current signed lifecycle eligibility before issuing a protected product session. 5. Refuse access when any link, membership, product approval, or freshness check is missing. One person can belong to multiple Institutions. Scope every product query to the selected Institution and local tenant. A central product eligibility grant does not invent a product role. ## Link an existing account The reviewed link workflow starts with a five-minute challenge. The person proves the existing local account with a fresh local credential and confirms the central identity through a purpose-bound OIDC callback. A different live Institution sponsor approves the exact local account, central issuer and subject, project, and Institution. The product's separately approved machine identity attests the proof. A typed evidence reference alone is insufficient. The management API exposes `/v1/link-challenges` and scoped challenge read, attest, approve, request, and exact acknowledgement routes. The product installs the approved link metadata with the corresponding lifecycle entity in one transaction, then acknowledges that exact version and proof. A generic cursor acknowledgement does not make a link effective. Pending approval, delivery, or acknowledgement is not product access. ## Revoke and rehire A departure or suspension removes the current authorization and should end local sessions. Rehire needs fresh sponsorship and product review. Never restore historical roles or clear a local reapproval requirement because an old `(iss, sub)` appears again. Test duplicate emails, changed emails, multiple Institutions, revoked sponsors, stale entity versions, and mismatched acknowledgements. --- # Eligibility and lifecycle An application must keep its local workforce access aligned with management's ordered signed feed. The feed contract is implemented by the Python service, while production product adapters and owned-issuer provisioning still need acceptance. ## Reviewed machine authority The current source requires an active, independently reviewed `lifecycle-consumer` grant bound to the exact signed issuer, subject and project. A role claim or account-link attestor grant is insufficient. Mixed machine roles are refused. A current project owner proposes the grant; a different platform project-approver reviews its exact version and digest. Local grant approval creates neither a client nor tokens. Owned issuer client-credentials issuance and live product provisioning remain separate acceptance gates. Verify the deployed API version before relying on these routes. A current scoped owner or platform reviewer can revoke the grant. Revocation is terminal: pending or effective grants cannot reactivate through an old receipt. When revocation commits before a waiting acknowledgement, that request is denied without advancing the project cursor. An already committed acknowledgement stays committed. Multiple credentials for one project share one logical consumer cursor, not independent proof that separate products applied changes. ## Poll and apply 1. Call `GET /v1/lifecycle/{project_id}?after=CURSOR` every 15 seconds using a dedicated project-scoped service access token. The response contains up to 500 signed `events`, a signed `receipt`, `next_cursor`, and `has_more`. 2. Verify the dedicated RS256 lifecycle key ID, signature, issuer, audience, kind, sequence, and receipt expiry. This key is separate from the issuer's OIDC JWKS. A gap, wrong project, stale version, or invalid signature must close protected access until catch-up. 3. Apply entity changes and advance your durable cursor in one database transaction. Duplicate events are safe. Send `POST /v1/lifecycle/{project_id}/ack` with `{"sequence": APPLIED_CURSOR}` only after the durable commit. The sequence is a strict integer from 0 to 2147483647. Equal-cursor retry is harmless; decreasing or above-head values are refused. If the cursor is invalid or history is missing, request `GET /v1/lifecycle/{project_id}/snapshot`. Verify the signed head and entities, rebuild safely, then resume the feed. Snapshot recovery currently refuses more than 5000 entities or 2 MiB of serialized entity data with 503, without signed truncation. Larger cohorts need an accepted recovery path; do not treat that refusal as a fresh receipt. ## Enforce freshness A signed receipt is valid for at most 60 seconds. Accept it only after applying all changes through its head. Protected workforce requests fail closed when that window expires. A service outage can leave access open only for the remaining valid receipt interval. Public documentation and unrelated anonymous routes can remain available. For revoked access, end local refresh sessions and protected real-time connections. A product's acknowledgement is required before central operations report effective delivery. Do not treat the existence of a queued outbox item as effective revocation. ## Independently review an exact grant A current Access record and an acknowledged lifecycle Event do not independently authorize an owned-issuer assignment. Historical requests without the decision evidence below need a new reviewed path. 1. An actual Institution Sponsor proposes the exact Access ID/version through `POST /v1/institutions/{institution_id}/access-grant-reviews`. 2. A different effective Institution administrator approves the resulting review through `/{review_id}/approve`. Both reviewers must differ from the beneficiary. Read `GET /v1/institutions/{institution_id}/access-grant-reviews` to inspect candidates, immutable review bindings and current facts. The portal exposes this workflow at `/organizations/{institution_id}/access`; sponsor-only access does not permit the other administrator areas. Inspect the beneficiary issuer/subject, Person and Membership versions, exact project/Event, reviewer generations, fingerprints and accepted Audit bindings. Proposals contain only `access_id`, `access_version` and `reason`; approval and review revocation contain only `reason`. Every decision needs recent strong authentication and a target-bound `Idempotency-Key`. POST returns an immutable receipt. Preserve the same exact body and key after response loss, then reread the scoped GET. `pending_review` has `current:false` until independent approval. An approved receipt does not guarantee that its review is still current. `delivery_acknowledged:true` requires the exact grant Event to be acknowledged and the project head to match the applied cursor. Reviewed client installation, signed assignment and product-local roles remain separate gates. Revoking a review retains its evidence and does not mutate the underlying Access record. [Browse the exact grant-review API](/docs/api/groups/reviewed-access-grants) for declared requests, response fields and examples. ## Personal portal state `GET /v1/me/freshness` returns a signed personal snapshot and receipt for audience `taifa-identity-portal`. The portal applies only nondecreasing versions and checks the exact issuer and subject. It requests fresh state at most 15 seconds after the previous receipt. The personal route is not a substitute for a product's project feed. ## Test the consumer The Node example has an in-memory poller and intentionally does not acknowledge a cursor. Run `npm test` in `examples/node` to inspect duplicate, gap, expiry, and signature refusal. Before production, replace memory with a durable transaction, test snapshot recovery, and verify real management and product integration. --- # Enrollment and recovery Strong sign-in and workforce admission are separate decisions. The Go issuer can verify password plus TOTP and optional passkeys for a synthetic local account. It cannot yet enroll a real person through the complete reviewed, holder-bound, Mail-delivered activation journey. ## Sign in with current factors The portal BFF starts an OIDC transaction and binds it to an HttpOnly challenge cookie, CSRF protection, and the private issuer challenge. Password plus TOTP produces `acr=taifa-mfa`. A registered passkey must prove user presence and verification and produces `acr=taifa-phishing-resistant`. A client may request stronger assurance; the verified result must actually meet it. Platform administration requires phishing-resistant assurance and an actual `auth_time` within five minutes. When passkeys are configured, the issuer exposes private authentication begin and finish routes to the BFF. Registration needs a recent strong session and a discoverable, user-verifying credential. The registration ceremony is versioned, one-use, and expires after at most two minutes. The BFF completes registration before the issuer consumes the OIDC auth request. These private routes are not an application SDK or a public enrollment API. ## Admit a real person A live Institution sponsor proposes a new central Person for the approved Institution. A different authorized reviewer approves the exact identity and context. The management service has fresh standalone enrollment records and private admission grant, acknowledgement, and activation-proof routes. Activation is disabled by default. The issuer's one-use grant acceptance, holder invitation, credential setup, quarantine release, and complete Mail bridge remain unwired. Do not mark a Person active on review alone or send a synthetic bootstrap credential to a real person. A delivery email is a way to reach a holder, not proof that the holder owns an existing local account or has completed factors. Admission must bind a one-use invitation to a protected portal session, finish real factors, obtain a management activation proof and a fresh authority lease, then release that exact credential generation. ## Recover access A lost factor or inaccessible account needs a separately audited, scoped review with independent approval and fresh strong reviewer authentication. Email possession alone cannot authorize privileged recovery. The old credential and session state must be contained, and a recovered account must retain the same issuer and subject unless a separately reviewed replacement identity is required. The owned issuer's complete recovery ceremony is a release gate. No self-service recovery URL is promised here. ## Verify before launch Test user-verifying passkeys on supported authenticators, password plus TOTP, lost-factor recovery, expired and repeated invitations, sponsor or reviewer revocation, cancellation during setup, Mail failure, and cross-service activation. See [platform status](/docs/platform-status) for the release boundary. --- # Credentials and rotation Identity uses several unrelated secrets. Rotate each through its own owner and validation path. Human logout does not revoke every machine credential or signing key. - **OIDC client secret:** Used by a confidential application backend. Keep one client per environment in a server-side secret manager, with reviewed rotation. - **OIDC signing key:** Used by the Go issuer. Store an owner-only RSA private file of at least 3072 bits, and publish the matching JWKS key ID. Multi-key rotation is a release gate. - **TOTP encryption and provider crypto keys:** Used by the Go issuer. Keep distinct 32-byte keys outside source control. - **Passkey encryption key:** Used by the Go issuer when enabled. Keep a separate 32-byte key and exact HTTPS relying-party origin. - **Lifecycle signing key:** Used by the Management publisher. Keep it separate from OIDC signing. Consumers pin its ID and verify signed events and receipts. - **Lifecycle or attestation service identity:** Used by a product backend. Use reviewed, project-scoped, renewed access. General issuance on the owned engine is still gated. - **Mail API key:** Used by the Management worker. Use a dedicated Identity machine credential scoped to sending and the approved sender. ## Controlled handoff for the owned issuer The owned issuer uses an operator-controlled credential delivery tool. Its qualified Linux implementation verifies a signed custody intent and receipt, writes the credential to a protected owner-only file, confirms durability, and acknowledges the handoff. It keeps credential material out of browser responses and command output. An uncertain acknowledgement requires fresh signed readback before deciding the outcome. Connected delivery has passed a Linux acceptance run joining the actual Management intent API, Go delivery command and private writer over verified TLS and PostgreSQL. It verified audited intent creation and private retrieval, durable credential handoff and acknowledgement, fresh signed readback, credential leakage checks and completed application shutdown. The owner and sponsorship facts were synthetic test fixtures, so this does not prove genuine human admission. Reviewed installation and activation still require completion. A completed custody handoff alone does not enable project sign-in. See [client registration](/docs/client-registration) for the separate review and release requirements. ## Request a credential intent The development API accepts `POST /v1/projects/{project_id}/owned-clients/credential-intents` from a current project owner with approved sponsorship and recent strong authentication. See the [typed custody API](/docs/api/groups/owned-client-custody). Send a bearer token for `taifa-management`, a unique `Idempotency-Key`, and this exact request shape: ```json { "client_id": "project-app", "client_version": 1, "destination_runtime": "owner-runtime", "reason": "Prepare the credential for the reviewed application deployment" } ``` The operator must already have configured that runtime for the project. The request cannot choose a filesystem path or another custodian. A successful response contains only the server-generated intent UUID and `custody_status: "pending"`. It contains no credential or signed intent. The intent lasts at most 120 seconds. Keep the same idempotency key and exact body after an uncertain response; retrying does not extend the deadline. Expired or revoked intent replays return 410. A new delivery attempt requires a new audited intent. During private retrieval, Management rechecks the captured owner, membership, project, audit evidence and configured destination. The delivery tool independently verifies the returned signed intent and exact binding. An earlier approval or response cannot restore revoked authority. Only the controlled owner runtime receives the credential file. A pending intent, a successful handoff and a reviewed client policy are separate facts. None alone establishes an installed, effective client. The complete registration and production rollout remain gated. ## Retain a preparation reference The Linux delivery tool can opt in to a protected checkpoint before creating the credential or acknowledging handoff. This retains the verified intent and initial receipt so a later process can identify the preparation without repeating prepare. The credential file still contains only its original 43-byte secret. Neither command prints a secret, signed receipt, preparation ID or filesystem path. An operator provisions the existing complete delivery configuration and this separate descriptor outside the repository. Configuration and evidence files must be process-owned regular files with mode `0600`; the custody root and private parents use `0700`. Both relative evidence destinations must differ from the credential destination and each other. Missing parents, symlinks, hard links, unsafe permissions and existing output files refuse. ```json { "schema": 1, "enabled": true, "delivery_config_file": "/srv/taifa-identity/private/delivery.json", "relative_checkpoint": "credential.checkpoint.json", "relative_proof": "credential.proof.json" } ``` The absolute configuration path above is illustrative. The operator binds the real project, owner, issuer, runtime, keys, TLS roots and credential destination in the protected delivery configuration. The descriptor cannot replace those bindings. The tools remain restricted to the isolated development deployment. Both commands require `AUTH_DEV_INSECURE_LOOPBACK=1` and the complete protected development configuration. 1. Run `auth-client-credential` with no arguments, selecting the existing configuration through `AUTH_CLIENT_CREDENTIAL_CONFIG_FILE` and the descriptor through `AUTH_CLIENT_CREDENTIAL_CHECKPOINT_CONFIG_FILE`. The successful output remains `controlled credential handoff complete`. Without the checkpoint variable, delivery retains its existing behavior. A checkpoint failure prevents credential creation and handoff acknowledgement. 2. After a successful handoff, run `auth-client-custody-proof` with no arguments and `AUTH_CLIENT_CUSTODY_PROOF_CONFIG_FILE` selecting the same descriptor. It verifies the retained checkpoint, exact credential bytes and a fresh signed private Go readback, then exclusively writes the configured proof. Success prints only `credential custody proof exported`. The original preparation must still be unconsumed and in `handoff_complete` state, before its original 24-hour deadline. It checks expiry after destination traversal and again after file durability checks. A later failure retains its artifact and reports failure. The proof contains the public preparation ID, exact client version as a decimal string, binding fingerprint, signed observation correlation and original deadlines. Its `verification` field is `server_readback_required`. It contains no secret, signed envelope, first secret hash, raw challenge or private path. The owner then supplies the preparation UUID as `credential_preparation_id` in the development [client-policy proposal](/docs/client-registration). Management independently obtains a fresh signed private readback for both proposal and approval. It does not accept the proof as current authorization or extend the original preparation deadline. This attachment implementation is undergoing combined qualification; installation and activation remain separate pending work. Historical completed deliveries without a checkpoint cannot recover their preparation ID automatically through this command. A missing, changed or conflicting checkpoint refuses. Repeating prepare is not an identifier lookup. Preserve failed artifacts for controlled investigation; do not overwrite them to force a retry. ## Legacy environment reveal and rotation The retained environment API has a one-time credential handoff for migration and rollback. A secret can be revealed only during its 15-minute window, then the encrypted copy is removed. An owner can request rotation with an approved overlap of at most 24 hours. Capture the new secret into deployment configuration immediately, switch traffic, and verify old credential refusal after overlap. The Go issuer does not use this legacy reveal or rotation path. ## Protect holder material Never log passwords, TOTP seeds, passkey records, recovery evidence, client secrets, access tokens, signed receipts, or invitation links. Keep private material in a dedicated secret store and make key IDs explicit in configuration. Back up encrypted state and old decryption keys while outstanding outbox work still needs them. If a key is compromised, contain affected sessions and clients, record the rotation, and recheck product acknowledgement rather than assuming a human logout covers machine access. --- # Taifa Mail Taifa Identity's owned enrollment flow connects the Go admission service to Management's transactional worker and Taifa Mail. The worker encrypts queued invitation payloads, submits Mail, polls the known message ID, and acknowledges delivery for the exact admission and generation. The Mail API credential stays in the server-side Management worker. Recovery and security message journeys, genuine holder acceptance, and production rollout remain release work. Mail delivery supports a workflow but does not prove a person's identity or make an approval effective. A delivered notice is separate from invitation redemption, required factor verification, signed activation, current workforce eligibility, and product acknowledgment. The historical provider mail adapter remains a migration artifact. ## Configure delivery Set `MAIL_API_URL` to an approved HTTPS origin only, `MAIL_API_KEY` to the Identity worker's private credential, and `MAIL_FROM_ADDRESS` to an approved allocated sender. The worker appends `/v1/emails/`; do not include that path in the origin setting. Keep the key on the server. It sends `Authorization: Bearer ...` and `X-Client: taifa-identity`, supplies the configured `from_` address, and forces `track_opens: false`. Mail must authorize the machine key for `emails:send` and the sender's Institution for `sending:compose`. Status polling also needs the key owner's `analytics:view` permission. A key that authenticates without these sender permissions cannot complete delivery. ## Interpret a send The API can return HTTP 202 with a message ID and `queued`, `sent`, `delivered`, or even `rejected` status. `queued` means accepted for processing, not delivered. The worker stores the Mail ID and polls its status. It distinguishes `accepted`, `delivered`, `failed`, and `ambiguous`. A malformed response or uncertain submission must be reconciled using the known ID where possible. Mail has no request-level idempotency contract for this send, so retrying an unknown submission blindly can duplicate an authentication message. An invitation or recovery workflow remains incomplete when required delivery fails. Existing password plus TOTP and passkey sign-in can continue during a Mail outage. Production acceptance needs a dedicated key, sender, permissions, feedback configuration, and a real approved recipient journey. ## Mail workforce login Mail's workforce product is a separate OIDC relying party. Its mobile and desktop profiles have fixed reviewed callback schemes, `openid profile email workforce-login` scopes, and a Mail API audience. The backend must validate the access token's issuer, audience, expiry and scope, then check the local officer account, current eligibility, assigned mailboxes, and Institution. It creates its own session keyed by issuer and subject. The generic native loopback example is not one of those fixed profiles, and the owned issuer has not registered these clients yet. --- # Errors and troubleshooting Start with the request ID, the operation that failed, and the boundary responsible for it. Redact tokens, passwords, TOTP seeds, passkey payloads, invitation links and private evidence before sharing diagnostics. | Symptom | Likely boundary | Next check | | --- | --- | --- | | Authorization callback has wrong state or nonce | Application login transaction | Discard the attempt and start again from `/login`; never replay a callback URL. | | Code exchange fails | Client and issuer | Confirm exact redirect, original PKCE verifier, one-use code, client secret where required, and issuer discovery. | | Token rejected by management | API authentication | Check signed issuer, `taifa-management` audience, expiry and JWKS; an ID token will not work. | | `403` after a valid login | Governance or product access | Check current Person, Institution, project, local account and role. | | `409` on mutation | Review or idempotency state | Compare request body and key, current approval, version and issuer binding. | | Lifecycle gate closes | Product consumer | Check dedicated signature, ordered cursor, receipt head, freshness and snapshot recovery. | | Mail request is pending or ambiguous | Delivery worker | Poll the saved provider ID and reconcile before resubmission. | | Owned issuer will not start | Release gate | Confirm disposable loopback mode, database name, exact portal client and required keys. Production startup is disabled. | ## Management response shapes Most management failures use `{"detail":"..."}`. Validation failures can return structured entries in `detail`. The API includes `X-Request-ID` in responses. Preserve it with the HTTP status and route, then inspect the exact schema in [management API](/docs/management-api). Do not parse the human detail string as a stable machine error code. ## Repeat safely A human mutation's `Idempotency-Key` is scoped to actor and request content. Retry the same key with the same body after an uncertain response. A changed body with the same key returns 409. Product installation and acknowledgement should also be idempotent, but use the exact lifecycle entity version or link binding as the unit of work. When authority freshness expires, restore connectivity and catch up before reopening protected access. --- # Availability and outages An issuer outage prevents new sign-ins and token refresh. A management or network outage can interrupt current eligibility delivery. Products may continue protected workforce access only while their last verified signed receipt remains valid, at most 60 seconds from issue. ## Product behavior Poll the lifecycle feed every 15 seconds. Apply through the signed receipt head before accepting it. If the feed fails, a sequence gap appears, or a receipt expires, close protected workforce routes until recovery and catch-up. An application can still serve public information or unrelated anonymous flows. Local sign-out should remain possible without fresh eligibility. ## Delivery behavior Approved governance actions are queued with durable work. `pending` means the product has not confirmed application. A product acknowledgement moves the exact projection toward effective status. Mail's `queued` or `sent` message state is not proof that a holder received it; failed or ambiguous delivery leaves an invitation or recovery incomplete. ## Recovery procedure Restore the failed service or connectivity, validate its issuer and signing keys, request a signed snapshot if the product's cursor is invalid, apply it transactionally, resume ordered events, then acknowledge the committed sequence. Reopen protected access only after a fresh receipt and local permission check. Operators should inspect `/v1/operations/diagnostics` and project diagnostics for stuck work and acknowledgement lag. Availability targets and recovery times require measured drills in the deployment's private runbooks. A documentation page is not evidence that a production target has been met. --- # Deployment The target deployment runs Taifa's Go issuer, Svelte portal, Python management service, PostgreSQL, and the required private worker and Mail connections. The issuer's production startup currently refuses to run, so this is a preparation and acceptance guide, not a production command sequence. ## Keep boundaries separate Expose only approved OIDC and portal routes through trusted HTTPS ingress. Keep the issuer's private challenge listener, management write API, database, machine admission routes, and worker traffic on private authenticated paths. The issuer string must remain stable through host or ingress changes because products use `(issuer, subject)` as their durable identity key. Use exact callback and WebAuthn origins; do not disable TLS validation to pass a preview. ## Select the owned issuer An issuer is the exact HTTPS identity of the authentication server. Configure Go with `AUTH_ISSUER` and connected services with the same `OIDC_ISSUER`. It identifies Taifa's own server, which exposes discovery and verification keys. It does not require an external authentication service or a `/realms/` path. Management requires an explicit `IDENTITY_PROVIDER=owned` selection. For an isolated prepared development deployment, the issuer configuration is: ```dotenv IDENTITY_ENV=development IDENTITY_PROVIDER=owned OWNED_DEVELOPMENT_ISSUER=https://localhost:19725 OIDC_ISSUER=https://localhost:19725 OIDC_JWKS_URL=https://localhost:19725/keys ``` The development pin must equal the issuer byte for byte. Only canonical HTTPS loopback origins are accepted. Use the prepared CA certificate through `OIDC_CA_BUNDLE` for Management's public discovery probe. Staging and production configuration pin the owned origins `https://accounts-staging.govconnect.ke` and `https://accounts.govconnect.ke`; accepting these URLs does not enable production startup. `IDENTITY_PROVIDER=keycloak` selects retained legacy migration operations. An absent selector defaults to that legacy mode for existing deployments. An invalid selector fails closed. Its realm issuer is a different identity from the owned origin, so changing this configuration does not migrate accounts or registrations. Legacy adapters and queued legacy provider actions refuse owned mode. The separate owned permission-catalog and client-policy review APIs remain available, with sign-in activation still requiring their unfinished private writer/readback acceptance. See [client registration](/docs/client-registration). ## Prepare state and secrets Apply database migrations in order to a scratch environment, then rehearse forward migration and restore with preserved credential, audit, idempotency, and outbox data. The auth service currently has forward-only credential migrations; destructive downgrades are not an acceptable rollback. Keep OIDC signing, lifecycle signing, TOTP encryption, passkey encryption, admission, Mail, and client secrets distinct. Restrict private key files to the service owner and document key IDs and rotation overlap. ## Prove release gates The isolated Go service uses development-only loopback listeners and disposable database checks. Before changing that guard, complete reviewed person provisioning and privileged admission, recovery, multi-client registration and SSO, central logout and back-channel revocation, key rotation, PostgreSQL 16 validation, rate limiting, real authenticator tests, lifecycle expiry and catch-up, Mail holder delivery, and product acknowledgement. Build an immutable release image and test restore and failover. Do not infer readiness from local unit tests. ## Roll out a product Register one reviewed client and one project-scoped lifecycle consumer per environment. Verify issuer discovery, exact redirects, signed token claims, Institution mapping, account linking, a revoked-user path, and product session shutdown in staging. Start with a small sponsored Institution and observe lifecycle lag and worker diagnostics before expanding. See [product migration](/docs/migration). --- # Product migration Move each product to the owned issuer without changing its local account IDs, records, roles, or tenant boundaries. The previous provider remains a migration and rollback artifact until the owned engine and each product pass acceptance. A client record or matching email is not a migration of a person. ## Inventory first Record current product accounts and role assignments, the exact central issuer and subject previously linked to each, Institution mappings, active sessions, callbacks, service identities, and revocation behavior. Identify accounts with duplicate or changed emails. Review every proposed new issuer and subject binding against local credential proof and current sponsorship; never bulk-link by email. ## Pilot one product 1. Complete owned-engine admission, client registration, logout, recovery, and key rotation gates in staging. 2. Register the product's web or native client and separate lifecycle consumer for the exact environment. 3. Link a small set of existing local accounts through the reviewed proof and sponsor flow. Require exact product acknowledgement after durable installation. 4. Test sign-in, local role refusal, cross-Institution isolation, suspension, rehire, stale lifecycle, session revocation, and account recovery. 5. Enable mandatory central sign-in only after the product's own acceptance record is complete. Support must keep agent and visitor identities separate. Sign retains recipient passcodes, consent and local document authorization. AI keeps explicit provisioning and its separate machine keys. Mail retains its delivery credential and checks local officer and mailbox authority after workforce login. Product-specific protocols must not be weakened to fit a shared sign-in page. ## Roll back safely Keep the guarded database and audit history. A rollback must not revive a person or role revoked after cutover. Contain affected sessions and clients, apply the latest central lifecycle state, and use a reviewed operator decision for ambiguous bindings. Never write previous-provider database tables directly. Do not treat a deployed old login screen as permission to restore a legacy bypass. --- # Operations and rollback Observe the difference between an approved decision, queued delivery, product acknowledgement, and effective access. The management API exposes scoped diagnostics so operators can identify lag without exposing private infrastructure in public documentation. ## Check the system `GET /health` reports a live management process. `GET /ready` checks expected schema tables and database access. Authorized operators can inspect `GET /v1/operations/diagnostics` and project-scoped diagnostics for failed or ambiguous work, worker observation, client drift, and lifecycle acknowledgement lag. `GET /v1/jobs` shows recent work status. Correlate a failed HTTP request with its `X-Request-ID` and redacted audit record. ## Handle ambiguous work Do not blindly repeat a provider write after a timeout or unknown response. Reconcile the saved provider reference and current target state, then use the reviewed retry or repair operation when its preconditions hold. For Mail, poll the stored message ID; a second POST can create a duplicate. For a product link, acknowledge only the exact installed version. For a lifecycle cursor, acknowledge only after the local transaction commits. ## Rotate and restore Rotate OIDC signing and lifecycle signing keys independently. Consumers need a coordinated key ID transition; an unexpected key must fail closed. Preserve encrypted credentials, old decryption keys for outstanding work, idempotency receipts, audit rows, and outbox entries through backup and restore. Prove that a restored product catches up from a signed snapshot before reopening access. ## Contain a failed rollout Disable the affected client or route, end local protected sessions, and hold new activation when its review or Mail path is incomplete. Keep the latest known revocations enforced. The old provider may remain available as a reviewed rollback artifact, but it must not silently restore access removed after cutover. Production rollback and emergency admission need private, independently reviewed runbooks and measured drills. --- # API reference Browse the management API by resource. - [Personal account](/docs/api/groups/personal-account) (4 operations) - [Credential actions](/docs/api/groups/credential-actions) (3 operations) - [Reviewed Access grants](/docs/api/groups/reviewed-access-grants) (4 operations) - [Lifecycle service authority](/docs/api/groups/lifecycle-service-authority) (5 operations) - [Institution federation](/docs/api/groups/institution-federation) (3 operations) - [Other](/docs/api/groups/other) (19 operations) - [Audit investigation](/docs/api/groups/audit-investigation) (2 operations) - [Workflows](/docs/api/groups/workflows) (28 operations) - [Staff enrollment](/docs/api/groups/staff-enrollment) (6 operations) - [Standalone workforce admission](/docs/api/groups/standalone-workforce-admission) (5 operations) - [Personal sessions](/docs/api/groups/personal-sessions) (2 operations) - [Account linking](/docs/api/groups/account-linking) (9 operations) - [Security incident sessions](/docs/api/groups/security-incident-sessions) (3 operations) - [Reviewed authentication policy](/docs/api/groups/reviewed-authentication-policy) (4 operations) - [Operations](/docs/api/groups/operations) (4 operations) - [Personal capabilities](/docs/api/groups/personal-capabilities) (14 operations) - [Reviewed project clients](/docs/api/groups/reviewed-project-clients) (8 operations) - [Owned client custody](/docs/api/groups/owned-client-custody) (1 operations) - [Project authority status](/docs/api/groups/project-authority-status) (1 operations) - [Project lifecycle](/docs/api/groups/project-lifecycle) (6 operations) # Personal account 4 management API operations. - [GET /v1/me](/docs/api/operations/me_v1_me_get): Me - [GET /v1/me/freshness](/docs/api/operations/freshness_v1_me_freshness_get): Freshness - [GET /v1/me/sessions](/docs/api/operations/sessions_v1_me_sessions_get): Sessions - [GET /v1/me/authenticators](/docs/api/operations/authenticators_v1_me_authenticators_get): Authenticators ## GET /v1/me Me Me Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters No path or query parameters declared. ### Request body This operation has no request body. ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | | string | Yes | | | `issuer` | | string | Yes | | | `subject` | | string | Yes | | | `status` | | active | Yes | | | `version` | | integer | Yes | | | `roles` | | string[] | Yes | | | `memberships` | | OwnMembership[] | Yes | | | `access` | | OwnAccess[] | Yes | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/me' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/me', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/me', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/me_v1_me_get) ## GET /v1/me/freshness Freshness Freshness Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters No path or query parameters declared. ### Request body This operation has no request body. ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `snapshot` | | string | Yes | Opaque signed snapshot JWT | | `receipt` | | string | Yes | Opaque signed receipt JWT | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/me/freshness' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/me/freshness', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/me/freshness', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/freshness_v1_me_freshness_get) ## GET /v1/me/sessions Sessions Sessions Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters No path or query parameters declared. ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/me/sessions' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/me/sessions', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/me/sessions', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/sessions_v1_me_sessions_get) ## GET /v1/me/authenticators Authenticators Authenticators Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters No path or query parameters declared. ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/me/authenticators' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/me/authenticators', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/me/authenticators', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/authenticators_v1_me_authenticators_get) --- # Credential actions 3 management API operations. - [GET /v1/me/credential-actions](/docs/api/operations/capabilities_v1_me_credential_actions_get): Capabilities - [POST /v1/me/credential-actions](/docs/api/operations/start_v1_me_credential_actions_post): Start - [POST /v1/me/credential-actions/{intent_id}/complete](/docs/api/operations/complete_v1_me_credential_actions__intent_id__complete_post): Complete ## GET /v1/me/credential-actions Capabilities Capabilities Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters No path or query parameters declared. ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/me/credential-actions' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/me/credential-actions', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/me/credential-actions', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/capabilities_v1_me_credential_actions_get) ## POST /v1/me/credential-actions Start Start Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `idempotency-key` | header | string \| null | No | | | `x-portal-binding` | header | string \| null | No | | ### Request body #### application/json Required; StartAction | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `action` | | string | Yes | Validation: min length 1; max length 64 | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 201 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/me/credential-actions' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "action": "REPLACE_WITH_ACTION", "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/me/credential-actions', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "action": "REPLACE_WITH_ACTION", "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/me/credential-actions', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"action":"REPLACE_WITH_ACTION","reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/start_v1_me_credential_actions_post) ## POST /v1/me/credential-actions/{intent_id}/complete Complete Complete Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `intent_id` | path | string | Yes | | | `idempotency-key` | header | string \| null | No | | | `x-portal-binding` | header | string \| null | No | | ### Request body #### application/json Required; FinishAction | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `callback_status` | | string | Yes | Validation: pattern ^(success\|canceled\|error)$ | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/me/credential-actions/REPLACE_WITH_INTENT_ID/complete' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "callback_status": "REPLACE_WITH_CALLBACK_STATUS" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/me/credential-actions/REPLACE_WITH_INTENT_ID/complete', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "callback_status": "REPLACE_WITH_CALLBACK_STATUS" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/me/credential-actions/REPLACE_WITH_INTENT_ID/complete', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"callback_status":"REPLACE_WITH_CALLBACK_STATUS"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/complete_v1_me_credential_actions__intent_id__complete_post) --- # Reviewed Access grants 4 management API operations. - [GET /v1/institutions/{institution_id}/access-grant-reviews](/docs/api/operations/list_scoped_v1_institutions__institution_id__access_grant_reviews_get): List exact Access grant reviews and candidates - [POST /v1/institutions/{institution_id}/access-grant-reviews](/docs/api/operations/propose_v1_institutions__institution_id__access_grant_reviews_post): Propose independent review of one Access version - [POST /v1/institutions/{institution_id}/access-grant-reviews/{review_id}/approve](/docs/api/operations/approve_v1_institutions__institution_id__access_grant_reviews__review_id__approve_post): Independently approve an exact Access review - [POST /v1/institutions/{institution_id}/access-grant-reviews/{review_id}/revoke](/docs/api/operations/revoke_v1_institutions__institution_id__access_grant_reviews__review_id__revoke_post): Revoke a reviewed Access decision ## GET /v1/institutions/{institution_id}/access-grant-reviews List exact Access grant reviews and candidates Requires a current actual Institution Sponsor or effective administrator with active membership. Current validity and product acknowledgement are read-time facts, not assignment authority. Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution` | | InstitutionDisplay | Yes | | | `reviews` | | GrantReviewRead[] | Yes | | | `candidates` | | GrantCandidate[] | Yes | | | `_actions` | | propose[] | Yes | | #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/access-grant-reviews' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/access-grant-reviews', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/access-grant-reviews', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example ```json { "_actions": [ "propose" ], "candidates": [], "institution": { "id": "00000000-0000-4000-8000-000000000030", "name": "Synthetic institution" }, "reviews": [] } ``` [Request and response examples](/docs/api/operations/list_scoped_v1_institutions__institution_id__access_grant_reviews_get) ## POST /v1/institutions/{institution_id}/access-grant-reviews Propose independent review of one Access version A current actual Sponsor proposes the exact active Access version. The accepted receipt records no issuer assignment. Exact idempotency replay returns the original receipt. Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; GrantProposal | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `access_id` | | string | Yes | Validation: min length 1; max length 200 | | `access_version` | | integer | Yes | Validation: minimum 1; maximum 9223372036854775807 | ### Responses #### 201 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | | string | Yes | | | `status` | | pending_review \| approved \| revoked \| superseded | Yes | | | `access_id` | | string | Yes | | | `access_version` | | integer | Yes | | | `project_id` | | string | Yes | | | `beneficiary_person_id` | | string | Yes | | | `beneficiary_issuer` | | string | Yes | | | `beneficiary_subject` | | string | Yes | | | `beneficiary_person_version` | | integer | Yes | | | `beneficiary_membership_id` | | string | Yes | | | `beneficiary_membership_version` | | integer | Yes | | | `event_id` | | string | Yes | | | `event_sequence` | | integer | Yes | | | `event_digest` | | string | Yes | | | `source_request_id` | | string \| null | Yes | | | `sponsor_id` | | string | Yes | | | `sponsor_generation` | | integer | Yes | | | `sponsor_actor` | | string | Yes | | | `sponsor_person_id` | | string | Yes | | | `sponsor_person_version` | | integer | Yes | | | `sponsor_membership_id` | | string | Yes | | | `sponsor_membership_version` | | integer | Yes | | | `sponsor_fingerprint` | | string | Yes | | | `sponsor_audit_id` | | string | Yes | | | `sponsor_operation` | | string | Yes | | | `sponsor_target` | | string | Yes | | | `administrator_proposal_id` | | string \| null | Yes | | | `administrator_generation` | | integer \| null | Yes | | | `administrator_actor` | | string \| null | Yes | | | `administrator_person_id` | | string \| null | Yes | | | `administrator_person_version` | | integer \| null | Yes | | | `administrator_membership_id` | | string \| null | Yes | | | `administrator_membership_version` | | integer \| null | Yes | | | `approved_fingerprint` | | string \| null | Yes | | | `administrator_audit_id` | | string \| null | Yes | | | `administrator_operation` | | string \| null | Yes | | | `administrator_target` | | string \| null | Yes | | | `created_at` | | string | Yes | | | `expires_at` | | string | Yes | | #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/access-grant-reviews' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "access_id": "00000000-0000-4000-8000-000000000001", "access_version": 1, "reason": "Request independent review of current case access" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/access-grant-reviews', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "access_id": "00000000-0000-4000-8000-000000000001", "access_version": 1, "reason": "Request independent review of current case access" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/access-grant-reviews', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"access_id":"00000000-0000-4000-8000-000000000001","access_version":1,"reason":"Request independent review of current case access"}') ) response.raise_for_status() ``` ### Response example ```json { "access_id": "00000000-0000-4000-8000-000000000011", "access_version": 2, "administrator_actor": "https://people.example.test|synthetic-administrator", "administrator_audit_id": "00000000-0000-4000-8000-000000000023", "administrator_generation": 2, "administrator_membership_id": "00000000-0000-4000-8000-000000000022", "administrator_membership_version": 1, "administrator_operation": "access-grant-review.approve:institution:review", "administrator_person_id": "00000000-0000-4000-8000-000000000021", "administrator_person_version": 2, "administrator_proposal_id": "00000000-0000-4000-8000-000000000020", "administrator_target": "00000000-0000-4000-8000-000000000010", "approved_fingerprint": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "beneficiary_issuer": "https://people.example.test", "beneficiary_membership_id": "00000000-0000-4000-8000-000000000014", "beneficiary_membership_version": 1, "beneficiary_person_id": "00000000-0000-4000-8000-000000000013", "beneficiary_person_version": 1, "beneficiary_subject": "synthetic-holder", "created_at": "2026-10-04T10:00:00+00:00", "event_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "event_id": "00000000-0000-4000-8000-000000000015", "event_sequence": 7, "expires_at": "2027-01-02T10:00:00+00:00", "id": "00000000-0000-4000-8000-000000000010", "project_id": "00000000-0000-4000-8000-000000000012", "sponsor_actor": "https://people.example.test|synthetic-sponsor", "sponsor_audit_id": "00000000-0000-4000-8000-000000000019", "sponsor_fingerprint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "sponsor_generation": 3, "sponsor_id": "00000000-0000-4000-8000-000000000016", "sponsor_membership_id": "00000000-0000-4000-8000-000000000018", "sponsor_membership_version": 2, "sponsor_operation": "access-grant-review.propose:institution:access", "sponsor_person_id": "00000000-0000-4000-8000-000000000017", "sponsor_person_version": 2, "sponsor_target": "00000000-0000-4000-8000-000000000010", "status": "approved" } ``` [Request and response examples](/docs/api/operations/propose_v1_institutions__institution_id__access_grant_reviews_post) ## POST /v1/institutions/{institution_id}/access-grant-reviews/{review_id}/approve Independently approve an exact Access review A distinct current effective administrator approves the locked Sponsor decision and exact grant Event. Dynamic validity is available from the scoped list. Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `review_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; identity__access_grant_review_router__Reason | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | | string | Yes | | | `status` | | pending_review \| approved \| revoked \| superseded | Yes | | | `access_id` | | string | Yes | | | `access_version` | | integer | Yes | | | `project_id` | | string | Yes | | | `beneficiary_person_id` | | string | Yes | | | `beneficiary_issuer` | | string | Yes | | | `beneficiary_subject` | | string | Yes | | | `beneficiary_person_version` | | integer | Yes | | | `beneficiary_membership_id` | | string | Yes | | | `beneficiary_membership_version` | | integer | Yes | | | `event_id` | | string | Yes | | | `event_sequence` | | integer | Yes | | | `event_digest` | | string | Yes | | | `source_request_id` | | string \| null | Yes | | | `sponsor_id` | | string | Yes | | | `sponsor_generation` | | integer | Yes | | | `sponsor_actor` | | string | Yes | | | `sponsor_person_id` | | string | Yes | | | `sponsor_person_version` | | integer | Yes | | | `sponsor_membership_id` | | string | Yes | | | `sponsor_membership_version` | | integer | Yes | | | `sponsor_fingerprint` | | string | Yes | | | `sponsor_audit_id` | | string | Yes | | | `sponsor_operation` | | string | Yes | | | `sponsor_target` | | string | Yes | | | `administrator_proposal_id` | | string \| null | Yes | | | `administrator_generation` | | integer \| null | Yes | | | `administrator_actor` | | string \| null | Yes | | | `administrator_person_id` | | string \| null | Yes | | | `administrator_person_version` | | integer \| null | Yes | | | `administrator_membership_id` | | string \| null | Yes | | | `administrator_membership_version` | | integer \| null | Yes | | | `approved_fingerprint` | | string \| null | Yes | | | `administrator_audit_id` | | string \| null | Yes | | | `administrator_operation` | | string \| null | Yes | | | `administrator_target` | | string \| null | Yes | | | `created_at` | | string | Yes | | | `expires_at` | | string | Yes | | #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/access-grant-reviews/REPLACE_WITH_REVIEW_ID/approve' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "Approve independently reviewed current access" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/access-grant-reviews/REPLACE_WITH_REVIEW_ID/approve', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "Approve independently reviewed current access" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/access-grant-reviews/REPLACE_WITH_REVIEW_ID/approve', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"Approve independently reviewed current access"}') ) response.raise_for_status() ``` ### Response example ```json { "access_id": "00000000-0000-4000-8000-000000000011", "access_version": 2, "administrator_actor": "https://people.example.test|synthetic-administrator", "administrator_audit_id": "00000000-0000-4000-8000-000000000023", "administrator_generation": 2, "administrator_membership_id": "00000000-0000-4000-8000-000000000022", "administrator_membership_version": 1, "administrator_operation": "access-grant-review.approve:institution:review", "administrator_person_id": "00000000-0000-4000-8000-000000000021", "administrator_person_version": 2, "administrator_proposal_id": "00000000-0000-4000-8000-000000000020", "administrator_target": "00000000-0000-4000-8000-000000000010", "approved_fingerprint": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "beneficiary_issuer": "https://people.example.test", "beneficiary_membership_id": "00000000-0000-4000-8000-000000000014", "beneficiary_membership_version": 1, "beneficiary_person_id": "00000000-0000-4000-8000-000000000013", "beneficiary_person_version": 1, "beneficiary_subject": "synthetic-holder", "created_at": "2026-10-04T10:00:00+00:00", "event_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "event_id": "00000000-0000-4000-8000-000000000015", "event_sequence": 7, "expires_at": "2027-01-02T10:00:00+00:00", "id": "00000000-0000-4000-8000-000000000010", "project_id": "00000000-0000-4000-8000-000000000012", "sponsor_actor": "https://people.example.test|synthetic-sponsor", "sponsor_audit_id": "00000000-0000-4000-8000-000000000019", "sponsor_fingerprint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "sponsor_generation": 3, "sponsor_id": "00000000-0000-4000-8000-000000000016", "sponsor_membership_id": "00000000-0000-4000-8000-000000000018", "sponsor_membership_version": 2, "sponsor_operation": "access-grant-review.propose:institution:access", "sponsor_person_id": "00000000-0000-4000-8000-000000000017", "sponsor_person_version": 2, "sponsor_target": "00000000-0000-4000-8000-000000000010", "status": "approved" } ``` [Request and response examples](/docs/api/operations/approve_v1_institutions__institution_id__access_grant_reviews__review_id__approve_post) ## POST /v1/institutions/{institution_id}/access-grant-reviews/{review_id}/revoke Revoke a reviewed Access decision Retains the immutable decision evidence while ending its review authority. It does not change the underlying Access grant. Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `review_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; identity__access_grant_review_router__Reason | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | | string | Yes | | | `status` | | pending_review \| approved \| revoked \| superseded | Yes | | | `access_id` | | string | Yes | | | `access_version` | | integer | Yes | | | `project_id` | | string | Yes | | | `beneficiary_person_id` | | string | Yes | | | `beneficiary_issuer` | | string | Yes | | | `beneficiary_subject` | | string | Yes | | | `beneficiary_person_version` | | integer | Yes | | | `beneficiary_membership_id` | | string | Yes | | | `beneficiary_membership_version` | | integer | Yes | | | `event_id` | | string | Yes | | | `event_sequence` | | integer | Yes | | | `event_digest` | | string | Yes | | | `source_request_id` | | string \| null | Yes | | | `sponsor_id` | | string | Yes | | | `sponsor_generation` | | integer | Yes | | | `sponsor_actor` | | string | Yes | | | `sponsor_person_id` | | string | Yes | | | `sponsor_person_version` | | integer | Yes | | | `sponsor_membership_id` | | string | Yes | | | `sponsor_membership_version` | | integer | Yes | | | `sponsor_fingerprint` | | string | Yes | | | `sponsor_audit_id` | | string | Yes | | | `sponsor_operation` | | string | Yes | | | `sponsor_target` | | string | Yes | | | `administrator_proposal_id` | | string \| null | Yes | | | `administrator_generation` | | integer \| null | Yes | | | `administrator_actor` | | string \| null | Yes | | | `administrator_person_id` | | string \| null | Yes | | | `administrator_person_version` | | integer \| null | Yes | | | `administrator_membership_id` | | string \| null | Yes | | | `administrator_membership_version` | | integer \| null | Yes | | | `approved_fingerprint` | | string \| null | Yes | | | `administrator_audit_id` | | string \| null | Yes | | | `administrator_operation` | | string \| null | Yes | | | `administrator_target` | | string \| null | Yes | | | `created_at` | | string | Yes | | | `expires_at` | | string | Yes | | #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/access-grant-reviews/REPLACE_WITH_REVIEW_ID/revoke' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "Approve independently reviewed current access" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/access-grant-reviews/REPLACE_WITH_REVIEW_ID/revoke', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "Approve independently reviewed current access" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/access-grant-reviews/REPLACE_WITH_REVIEW_ID/revoke', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"Approve independently reviewed current access"}') ) response.raise_for_status() ``` ### Response example ```json { "access_id": "00000000-0000-4000-8000-000000000011", "access_version": 2, "administrator_actor": "https://people.example.test|synthetic-administrator", "administrator_audit_id": "00000000-0000-4000-8000-000000000023", "administrator_generation": 2, "administrator_membership_id": "00000000-0000-4000-8000-000000000022", "administrator_membership_version": 1, "administrator_operation": "access-grant-review.approve:institution:review", "administrator_person_id": "00000000-0000-4000-8000-000000000021", "administrator_person_version": 2, "administrator_proposal_id": "00000000-0000-4000-8000-000000000020", "administrator_target": "00000000-0000-4000-8000-000000000010", "approved_fingerprint": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "beneficiary_issuer": "https://people.example.test", "beneficiary_membership_id": "00000000-0000-4000-8000-000000000014", "beneficiary_membership_version": 1, "beneficiary_person_id": "00000000-0000-4000-8000-000000000013", "beneficiary_person_version": 1, "beneficiary_subject": "synthetic-holder", "created_at": "2026-10-04T10:00:00+00:00", "event_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "event_id": "00000000-0000-4000-8000-000000000015", "event_sequence": 7, "expires_at": "2027-01-02T10:00:00+00:00", "id": "00000000-0000-4000-8000-000000000010", "project_id": "00000000-0000-4000-8000-000000000012", "sponsor_actor": "https://people.example.test|synthetic-sponsor", "sponsor_audit_id": "00000000-0000-4000-8000-000000000019", "sponsor_fingerprint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "sponsor_generation": 3, "sponsor_id": "00000000-0000-4000-8000-000000000016", "sponsor_membership_id": "00000000-0000-4000-8000-000000000018", "sponsor_membership_version": 2, "sponsor_operation": "access-grant-review.propose:institution:access", "sponsor_person_id": "00000000-0000-4000-8000-000000000017", "sponsor_person_version": 2, "sponsor_target": "00000000-0000-4000-8000-000000000010", "status": "approved" } ``` [Request and response examples](/docs/api/operations/revoke_v1_institutions__institution_id__access_grant_reviews__review_id__revoke_post) --- # Lifecycle service authority 5 management API operations. - [POST /v1/projects/{project_id}/lifecycle-service-grants](/docs/api/operations/propose_v1_projects__project_id__lifecycle_service_grants_post): Propose - [GET /v1/projects/{project_id}/lifecycle-service-grants](/docs/api/operations/listing_v1_projects__project_id__lifecycle_service_grants_get): Listing - [POST /v1/projects/{project_id}/lifecycle-service-grants/{grant_id}/approve](/docs/api/operations/approve_v1_projects__project_id__lifecycle_service_grants__grant_id__approve_post): Approve - [POST /v1/projects/{project_id}/lifecycle-service-grants/{grant_id}/revoke](/docs/api/operations/revoke_v1_projects__project_id__lifecycle_service_grants__grant_id__revoke_post): Revoke - [GET /v1/projects/{project_id}/lifecycle-service-grants/{grant_id}](/docs/api/operations/detail_v1_projects__project_id__lifecycle_service_grants__grant_id__get): Detail ## POST /v1/projects/{project_id}/lifecycle-service-grants Propose Propose Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; LifecycleServiceProposal | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `issuer` | | string | Yes | Validation: min length 1; max length 2048 | | `subject` | | string | Yes | Validation: min length 1; max length 255 | ### Responses #### 201 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | | string | Yes | | | `project_id` | | string | Yes | | | `issuer` | | string | Yes | | | `subject` | | string | Yes | | | `capability` | | lifecycle-consumer | Yes | | | `status` | | pending_review \| effective \| revoked | Yes | | | `active` | | boolean | Yes | | | `version` | | integer | Yes | Validation: minimum 1; maximum 3 | | `proposal_digest` | | string | Yes | Validation: pattern ^[a-f0-9]{64}$ | | `proposer` | | string | Yes | | | `approver` | | string \| null | Yes | | | `proposal_audit_id` | | string | Yes | | | `approval_audit_id` | | string \| null | Yes | | | `revocation_audit_id` | | string \| null | Yes | | | `created_at` | | string ยท date-time | Yes | | | `approved_at` | | string \| null | Yes | | | `revoked_at` | | string \| null | Yes | | #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle-service-grants' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "issuer": "REPLACE_WITH_ISSUER", "subject": "REPLACE_WITH_SUBJECT" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle-service-grants', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "issuer": "REPLACE_WITH_ISSUER", "subject": "REPLACE_WITH_SUBJECT" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle-service-grants', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","issuer":"REPLACE_WITH_ISSUER","subject":"REPLACE_WITH_SUBJECT"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/propose_v1_projects__project_id__lifecycle_service_grants_post) ## GET /v1/projects/{project_id}/lifecycle-service-grants Listing Listing Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `limit` | query | string | No | Validation: pattern ^(?:[1-9]\|[1-9][0-9]\|100)$ | | `after_id` | query | string ยท uuid \| null | No | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `[].id` | | string | Yes | | | `[].project_id` | | string | Yes | | | `[].issuer` | | string | Yes | | | `[].subject` | | string | Yes | | | `[].capability` | | lifecycle-consumer | Yes | | | `[].status` | | pending_review \| effective \| revoked | Yes | | | `[].active` | | boolean | Yes | | | `[].version` | | integer | Yes | Validation: minimum 1; maximum 3 | | `[].proposal_digest` | | string | Yes | Validation: pattern ^[a-f0-9]{64}$ | | `[].proposer` | | string | Yes | | | `[].approver` | | string \| null | Yes | | | `[].proposal_audit_id` | | string | Yes | | | `[].approval_audit_id` | | string \| null | Yes | | | `[].revocation_audit_id` | | string \| null | Yes | | | `[].created_at` | | string ยท date-time | Yes | | | `[].approved_at` | | string \| null | Yes | | | `[].revoked_at` | | string \| null | Yes | | #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle-service-grants' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle-service-grants', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle-service-grants', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/listing_v1_projects__project_id__lifecycle_service_grants_get) ## POST /v1/projects/{project_id}/lifecycle-service-grants/{grant_id}/approve Approve Approve Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `grant_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; LifecycleServiceApproval | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `expected_version` | | integer | Yes | Validation: minimum 1 | | `proposal_digest` | | string | Yes | Validation: pattern ^[a-f0-9]{64}$ | ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | | string | Yes | | | `project_id` | | string | Yes | | | `issuer` | | string | Yes | | | `subject` | | string | Yes | | | `capability` | | lifecycle-consumer | Yes | | | `status` | | pending_review \| effective \| revoked | Yes | | | `active` | | boolean | Yes | | | `version` | | integer | Yes | Validation: minimum 1; maximum 3 | | `proposal_digest` | | string | Yes | Validation: pattern ^[a-f0-9]{64}$ | | `proposer` | | string | Yes | | | `approver` | | string \| null | Yes | | | `proposal_audit_id` | | string | Yes | | | `approval_audit_id` | | string \| null | Yes | | | `revocation_audit_id` | | string \| null | Yes | | | `created_at` | | string ยท date-time | Yes | | | `approved_at` | | string \| null | Yes | | | `revoked_at` | | string \| null | Yes | | #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle-service-grants/REPLACE_WITH_GRANT_ID/approve' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "expected_version": 0, "proposal_digest": "REPLACE_WITH_PROPOSAL_DIGEST" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle-service-grants/REPLACE_WITH_GRANT_ID/approve', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "expected_version": 0, "proposal_digest": "REPLACE_WITH_PROPOSAL_DIGEST" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle-service-grants/REPLACE_WITH_GRANT_ID/approve', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","expected_version":0,"proposal_digest":"REPLACE_WITH_PROPOSAL_DIGEST"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/approve_v1_projects__project_id__lifecycle_service_grants__grant_id__approve_post) ## POST /v1/projects/{project_id}/lifecycle-service-grants/{grant_id}/revoke Revoke Revoke Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `grant_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; LifecycleServiceRevocation | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `expected_version` | | integer | Yes | Validation: minimum 1 | ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | | string | Yes | | | `project_id` | | string | Yes | | | `issuer` | | string | Yes | | | `subject` | | string | Yes | | | `capability` | | lifecycle-consumer | Yes | | | `status` | | pending_review \| effective \| revoked | Yes | | | `active` | | boolean | Yes | | | `version` | | integer | Yes | Validation: minimum 1; maximum 3 | | `proposal_digest` | | string | Yes | Validation: pattern ^[a-f0-9]{64}$ | | `proposer` | | string | Yes | | | `approver` | | string \| null | Yes | | | `proposal_audit_id` | | string | Yes | | | `approval_audit_id` | | string \| null | Yes | | | `revocation_audit_id` | | string \| null | Yes | | | `created_at` | | string ยท date-time | Yes | | | `approved_at` | | string \| null | Yes | | | `revoked_at` | | string \| null | Yes | | #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle-service-grants/REPLACE_WITH_GRANT_ID/revoke' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "expected_version": 0 }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle-service-grants/REPLACE_WITH_GRANT_ID/revoke', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "expected_version": 0 }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle-service-grants/REPLACE_WITH_GRANT_ID/revoke', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","expected_version":0}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/revoke_v1_projects__project_id__lifecycle_service_grants__grant_id__revoke_post) ## GET /v1/projects/{project_id}/lifecycle-service-grants/{grant_id} Detail Detail Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `grant_id` | path | string | Yes | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | | string | Yes | | | `project_id` | | string | Yes | | | `issuer` | | string | Yes | | | `subject` | | string | Yes | | | `capability` | | lifecycle-consumer | Yes | | | `status` | | pending_review \| effective \| revoked | Yes | | | `active` | | boolean | Yes | | | `version` | | integer | Yes | Validation: minimum 1; maximum 3 | | `proposal_digest` | | string | Yes | Validation: pattern ^[a-f0-9]{64}$ | | `proposer` | | string | Yes | | | `approver` | | string \| null | Yes | | | `proposal_audit_id` | | string | Yes | | | `approval_audit_id` | | string \| null | Yes | | | `revocation_audit_id` | | string \| null | Yes | | | `created_at` | | string ยท date-time | Yes | | | `approved_at` | | string \| null | Yes | | | `revoked_at` | | string \| null | Yes | | #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle-service-grants/REPLACE_WITH_GRANT_ID' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle-service-grants/REPLACE_WITH_GRANT_ID', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle-service-grants/REPLACE_WITH_GRANT_ID', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/detail_v1_projects__project_id__lifecycle_service_grants__grant_id__get) --- # Institution federation 3 management API operations. - [GET /v1/institutions/{institution_id}/federation/deployments](/docs/api/operations/inventory_v1_institutions__institution_id__federation_deployments_get): Inventory - [POST /v1/institutions/{institution_id}/federation/deployments](/docs/api/operations/propose_v1_institutions__institution_id__federation_deployments_post): Propose - [POST /v1/institutions/{institution_id}/federation/deployments/{identifier}/approve](/docs/api/operations/approve_v1_institutions__institution_id__federation_deployments__identifier__approve_post): Approve ## GET /v1/institutions/{institution_id}/federation/deployments Inventory Inventory Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/federation/deployments' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/federation/deployments', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/federation/deployments', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/inventory_v1_institutions__institution_id__federation_deployments_get) ## POST /v1/institutions/{institution_id}/federation/deployments Propose Propose Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; FederationProposal | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `protocol` | | oidc \| saml | Yes | | | `issuer` | | string | Yes | Validation: min length 1; max length 512 | | `metadata_url` | | string | Yes | Validation: min length 1; max length 2000 | | `alias` | | string | Yes | Validation: pattern ^[a-z][a-z0-9-]{2,56}$ | | `assurance_evidence_reference` | | string | Yes | Validation: min length 5; max length 500 | | `upstream_client_id` | | string \| null | No | | | `secret_reference` | | string \| null | No | | ### Responses #### 201 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/federation/deployments' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "protocol": "REPLACE_WITH_PROTOCOL", "issuer": "REPLACE_WITH_ISSUER", "metadata_url": "REPLACE_WITH_METADATA_URL", "alias": "REPLACE_WITH_ALIAS", "assurance_evidence_reference": "REPLACE_WITH_ASSURANCE_EVIDENCE_REFERENCE" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/federation/deployments', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "protocol": "REPLACE_WITH_PROTOCOL", "issuer": "REPLACE_WITH_ISSUER", "metadata_url": "REPLACE_WITH_METADATA_URL", "alias": "REPLACE_WITH_ALIAS", "assurance_evidence_reference": "REPLACE_WITH_ASSURANCE_EVIDENCE_REFERENCE" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/federation/deployments', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","protocol":"REPLACE_WITH_PROTOCOL","issuer":"REPLACE_WITH_ISSUER","metadata_url":"REPLACE_WITH_METADATA_URL","alias":"REPLACE_WITH_ALIAS","assurance_evidence_reference":"REPLACE_WITH_ASSURANCE_EVIDENCE_REFERENCE"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/propose_v1_institutions__institution_id__federation_deployments_post) ## POST /v1/institutions/{institution_id}/federation/deployments/{identifier}/approve Approve Approve Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `identifier` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; identity__federation_router__Reason | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/federation/deployments/REPLACE_WITH_IDENTIFIER/approve' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/federation/deployments/REPLACE_WITH_IDENTIFIER/approve', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/federation/deployments/REPLACE_WITH_IDENTIFIER/approve', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/approve_v1_institutions__institution_id__federation_deployments__identifier__approve_post) --- # Other 19 management API operations. - [GET /v1/institutions](/docs/api/operations/institutions_v1_institutions_get): Institutions - [POST /v1/institutions](/docs/api/operations/create_institution_v1_institutions_post): Create Institution - [POST /v1/institutions/{institution_id}/approve](/docs/api/operations/approve_institution_v1_institutions__institution_id__approve_post): Approve Institution - [GET /v1/people](/docs/api/operations/people_v1_people_get): People - [POST /v1/people](/docs/api/operations/create_person_v1_people_post): Create Person - [GET /v1/projects](/docs/api/operations/projects_v1_projects_get): Projects - [POST /v1/projects](/docs/api/operations/create_project_v1_projects_post): Create Project - [POST /v1/access](/docs/api/operations/access_v1_access_post): Access - [GET /v1/access](/docs/api/operations/access_list_v1_access_get): Access List - [GET /v1/audit](/docs/api/operations/audit_v1_audit_get): Audit - [GET /v1/operations](/docs/api/operations/operations_v1_operations_get): Operations - [GET /v1/lifecycle/{project_id}](/docs/api/operations/feed_v1_lifecycle__project_id__get): Feed - [POST /v1/lifecycle/{project_id}/ack](/docs/api/operations/acknowledge_v1_lifecycle__project_id__ack_post): Acknowledge - [POST /v1/projects/{project_id}/approve](/docs/api/operations/approve_project_v1_projects__project_id__approve_post): Approve Project - [POST /v1/memberships](/docs/api/operations/membership_v1_memberships_post): Membership - [GET /v1/lifecycle/{project_id}/snapshot](/docs/api/operations/snapshot_v1_lifecycle__project_id__snapshot_get): Snapshot - [GET /v1/institutions/{institution_id}/members](/docs/api/operations/members_v1_institutions__institution_id__members_get): Members - [POST /v1/people/{person_id}/suspend](/docs/api/operations/suspend_v1_people__person_id__suspend_post): Suspend - [GET /v1/jobs](/docs/api/operations/jobs_v1_jobs_get): Jobs ## GET /v1/institutions Institutions Institutions Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters No path or query parameters declared. ### Request body This operation has no request body. ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `[].id` | InstitutionForOperator | string | Yes | | | `[].name` | InstitutionForOperator | string | Yes | | | `[].status` | InstitutionForOperator | string | Yes | | | `[].proposer` | InstitutionForOperator | string | Yes | | | `[].approver` | InstitutionForOperator | string \| null | Yes | | | `[].evidence_reference` | InstitutionForOperator | string | Yes | | | `[].can_review_evidence` | InstitutionForOperator | true | Yes | | | `[].id` | InstitutionForAdministrator | string | Yes | | | `[].name` | InstitutionForAdministrator | string | Yes | | | `[].status` | InstitutionForAdministrator | string | Yes | | | `[].proposer` | InstitutionForAdministrator | string | Yes | | | `[].approver` | InstitutionForAdministrator | string \| null | Yes | | | `[].can_review_evidence` | InstitutionForAdministrator | false | Yes | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/institutions' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/institutions', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/institutions_v1_institutions_get) ## POST /v1/institutions Create Institution Create Institution Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; InstitutionCreate | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `name` | | string | Yes | Validation: min length 2; max length 200 | | `evidence_reference` | | string | Yes | Validation: min length 5; max length 500 | ### Responses #### 201 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/institutions' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "name": "REPLACE_WITH_NAME", "evidence_reference": "REPLACE_WITH_EVIDENCE_REFERENCE" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "name": "REPLACE_WITH_NAME", "evidence_reference": "REPLACE_WITH_EVIDENCE_REFERENCE" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/institutions', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","name":"REPLACE_WITH_NAME","evidence_reference":"REPLACE_WITH_EVIDENCE_REFERENCE"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/create_institution_v1_institutions_post) ## POST /v1/institutions/{institution_id}/approve Approve Institution Approve Institution Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; Mutation | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/approve' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/approve', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/approve', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/approve_institution_v1_institutions__institution_id__approve_post) ## GET /v1/people People People Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters No path or query parameters declared. ### Request body This operation has no request body. ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `[].id` | | string | Yes | | | `[].issuer` | | string | Yes | | | `[].subject` | | string | Yes | | | `[].enabled` | | boolean | Yes | | | `[].version` | | integer | Yes | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/people' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/people', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/people', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/people_v1_people_get) ## POST /v1/people Create Person Create Person Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; PersonCreate | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `issuer` | | string | Yes | | | `subject` | | string | Yes | Validation: min length 1 | ### Responses #### 201 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/people' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "issuer": "REPLACE_WITH_ISSUER", "subject": "REPLACE_WITH_SUBJECT" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/people', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "issuer": "REPLACE_WITH_ISSUER", "subject": "REPLACE_WITH_SUBJECT" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/people', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","issuer":"REPLACE_WITH_ISSUER","subject":"REPLACE_WITH_SUBJECT"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/create_person_v1_people_post) ## GET /v1/projects Projects Projects Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters No path or query parameters declared. ### Request body This operation has no request body. ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `[].id` | | string | Yes | | | `[].name` | | string | Yes | | | `[].owner` | | string | Yes | | | `[].status` | | string | Yes | | | `[].head` | | integer | Yes | | | `[].acknowledged` | | integer | Yes | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/projects' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/projects', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/projects_v1_projects_get) ## POST /v1/projects Create Project Create Project Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; ProjectCreate | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `name` | | string | Yes | Validation: min length 2 | ### Responses #### 201 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "name": "REPLACE_WITH_NAME" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "name": "REPLACE_WITH_NAME" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","name":"REPLACE_WITH_NAME"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/create_project_v1_projects_post) ## POST /v1/access Access Access Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; AccessChange | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `person_id` | | string | Yes | | | `institution_id` | | string | Yes | | | `project_id` | | string | Yes | | | `active` | | boolean | Yes | | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/access' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "person_id": "REPLACE_WITH_PERSON_ID", "institution_id": "REPLACE_WITH_INSTITUTION_ID", "project_id": "REPLACE_WITH_PROJECT_ID", "active": false }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/access', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "person_id": "REPLACE_WITH_PERSON_ID", "institution_id": "REPLACE_WITH_INSTITUTION_ID", "project_id": "REPLACE_WITH_PROJECT_ID", "active": false }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/access', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","person_id":"REPLACE_WITH_PERSON_ID","institution_id":"REPLACE_WITH_INSTITUTION_ID","project_id":"REPLACE_WITH_PROJECT_ID","active":false}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/access_v1_access_post) ## GET /v1/access Access List Access List Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters No path or query parameters declared. ### Request body This operation has no request body. ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `[].id` | | string | Yes | | | `[].person_id` | | string | Yes | | | `[].institution_id` | | string | Yes | | | `[].project_id` | | string | Yes | | | `[].active` | | boolean | Yes | | | `[].version` | | integer | Yes | | | `[].approved_link` | | object \| null | Yes | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/access' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/access', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/access', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/access_list_v1_access_get) ## GET /v1/audit Audit Audit Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters No path or query parameters declared. ### Request body This operation has no request body. ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `[].id` | | string | Yes | | | `[].actor` | | string | Yes | | | `[].operation` | | string | Yes | | | `[].target` | | string | Yes | | | `[].institution_id` | | string \| null | Yes | | | `[].request_id` | | string | Yes | | | `[].reason` | | string | Yes | | | `[].outcome` | | string | Yes | | | `[].changes` | | object | Yes | | | `[].created_at` | | string | Yes | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/audit' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/audit', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/audit', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/audit_v1_audit_get) ## GET /v1/operations Operations Operations Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters No path or query parameters declared. ### Request body This operation has no request body. ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `pending` | | integer | Yes | | | `failed` | | integer | Yes | | | `failure_diagnostics_available` | | boolean | Yes | | | `status` | | failed \| pending \| effective | Yes | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/operations' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/operations', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/operations', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/operations_v1_operations_get) ## GET /v1/lifecycle/{project_id} Feed Feed Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `after` | query | integer | No | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `events` | | string[] | Yes | Opaque signed event JWTs | | `receipt` | | string | Yes | Opaque signed receipt JWT | | `next_cursor` | | integer | Yes | | | `has_more` | | boolean | Yes | | #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/lifecycle/REPLACE_WITH_PROJECT_ID' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/lifecycle/REPLACE_WITH_PROJECT_ID', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/lifecycle/REPLACE_WITH_PROJECT_ID', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/feed_v1_lifecycle__project_id__get) ## POST /v1/lifecycle/{project_id}/ack Acknowledge Acknowledge Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | ### Request body #### application/json Required; Acknowledgement | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `sequence` | | integer | Yes | Validation: minimum 0; maximum 2147483647 | ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `head` | | integer | Yes | | | `acknowledged` | | integer | Yes | | | `status` | | pending \| effective | Yes | | #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/lifecycle/REPLACE_WITH_PROJECT_ID/ack' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ --data '{ "sequence": 0 }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/lifecycle/REPLACE_WITH_PROJECT_ID/ack', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ "sequence": 0 }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/lifecycle/REPLACE_WITH_PROJECT_ID/ack', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']}, json=json.loads('{"sequence":0}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/acknowledge_v1_lifecycle__project_id__ack_post) ## POST /v1/projects/{project_id}/approve Approve Project Approve Project Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; Mutation | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/approve' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/approve', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/approve', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/approve_project_v1_projects__project_id__approve_post) ## POST /v1/memberships Membership Membership Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; MembershipChange | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `person_id` | | string | Yes | | | `institution_id` | | string | Yes | | | `active` | | boolean | Yes | | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/memberships' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "person_id": "REPLACE_WITH_PERSON_ID", "institution_id": "REPLACE_WITH_INSTITUTION_ID", "active": false }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/memberships', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "person_id": "REPLACE_WITH_PERSON_ID", "institution_id": "REPLACE_WITH_INSTITUTION_ID", "active": false }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/memberships', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","person_id":"REPLACE_WITH_PERSON_ID","institution_id":"REPLACE_WITH_INSTITUTION_ID","active":false}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/membership_v1_memberships_post) ## GET /v1/lifecycle/{project_id}/snapshot Snapshot Snapshot Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `snapshot` | | string | Yes | Opaque signed snapshot JWT | #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/lifecycle/REPLACE_WITH_PROJECT_ID/snapshot' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/lifecycle/REPLACE_WITH_PROJECT_ID/snapshot', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/lifecycle/REPLACE_WITH_PROJECT_ID/snapshot', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/snapshot_v1_lifecycle__project_id__snapshot_get) ## GET /v1/institutions/{institution_id}/members Members Members Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `[].id` | | string | Yes | | | `[].person_id` | | string | Yes | | | `[].institution_id` | | string | Yes | | | `[].active` | | boolean | Yes | | | `[].sponsor` | | string | Yes | | | `[].version` | | integer | Yes | | #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/members' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/members', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/members', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/members_v1_institutions__institution_id__members_get) ## POST /v1/people/{person_id}/suspend Suspend Suspend Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `person_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; Mutation | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/people/REPLACE_WITH_PERSON_ID/suspend' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/people/REPLACE_WITH_PERSON_ID/suspend', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/people/REPLACE_WITH_PERSON_ID/suspend', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/suspend_v1_people__person_id__suspend_post) ## GET /v1/jobs Jobs Jobs Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters No path or query parameters declared. ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/jobs' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/jobs', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/jobs', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/jobs_v1_jobs_get) --- # Audit investigation 2 management API operations. - [GET /v1/audit/search](/docs/api/operations/search_v1_audit_search_get): Search - [GET /v1/audit/export](/docs/api/operations/export_v1_audit_export_get): Export ## GET /v1/audit/search Search Search Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | query | string \| null | No | | | `actor` | query | string \| null | No | | | `operation` | query | string \| null | No | | | `outcome` | query | string \| null | No | | | `target` | query | string \| null | No | | | `since` | query | string \| null | No | | | `until` | query | string \| null | No | | | `cursor` | query | string \| null | No | | | `limit` | query | integer | No | Validation: minimum 1; maximum 1000 | ### Request body This operation has no request body. ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `items` | | AuditRead[] | Yes | | | `next_cursor` | | string \| null | Yes | | | `limit` | | integer | Yes | | #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/audit/search' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/audit/search', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/audit/search', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/search_v1_audit_search_get) ## GET /v1/audit/export Export Export Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | query | string \| null | No | | | `actor` | query | string \| null | No | | | `operation` | query | string \| null | No | | | `outcome` | query | string \| null | No | | | `target` | query | string \| null | No | | | `since` | query | string \| null | No | | | `until` | query | string \| null | No | | | `cursor` | query | string \| null | No | | | `limit` | query | integer | No | Validation: minimum 1; maximum 1000 | ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/audit/export' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/audit/export', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/audit/export', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/export_v1_audit_export_get) --- # Workflows 28 management API operations. - [GET /v1/registration-context](/docs/api/operations/deployment_context_v1_registration_context_get): Deployment Context - [POST /v1/institutions/{institution_id}/administrators](/docs/api/operations/propose_admin_v1_institutions__institution_id__administrators_post): Propose Admin - [POST /v1/institutions/{institution_id}/administrators/{proposal_id}/approve](/docs/api/operations/approve_admin_v1_institutions__institution_id__administrators__proposal_id__approve_post): Approve Admin - [POST /v1/institutions/{institution_id}/domains](/docs/api/operations/propose_domain_v1_institutions__institution_id__domains_post): Propose Domain - [POST /v1/institutions/{institution_id}/domains/{domain_id}/verify](/docs/api/operations/verify_domain_v1_institutions__institution_id__domains__domain_id__verify_post): Verify Domain - [POST /v1/institutions/{institution_id}/sponsors](/docs/api/operations/sponsor_change_v1_institutions__institution_id__sponsors_post): Sponsor Change - [POST /v1/institutions/{institution_id}/invitations](/docs/api/operations/invite_v1_institutions__institution_id__invitations_post): Invite - [POST /v1/invitations/{invitation_id}/redeem](/docs/api/operations/redeem_v1_invitations__invitation_id__redeem_post): Redeem - [POST /v1/institutions/{institution_id}/account-proofs](/docs/api/operations/proof_v1_institutions__institution_id__account_proofs_post): Proof - [POST /v1/link-requests](/docs/api/operations/request_link_v1_link_requests_post): Request Link - [POST /v1/link-requests/{request_id}/approve](/docs/api/operations/approve_link_v1_link_requests__request_id__approve_post): Approve Link - [POST /v1/institutions/{institution_id}/recovery-requests](/docs/api/operations/recovery_v1_institutions__institution_id__recovery_requests_post): Recovery - [POST /v1/recovery-requests/{request_id}/approve](/docs/api/operations/approve_recovery_v1_recovery_requests__request_id__approve_post): Approve Recovery - [POST /v1/projects/{project_id}/owners](/docs/api/operations/owner_v1_projects__project_id__owners_post): Owner - [POST /v1/projects/{project_id}/environments](/docs/api/operations/environment_v1_projects__project_id__environments_post): Environment - [GET /v1/projects/{project_id}/environments](/docs/api/operations/environments_v1_projects__project_id__environments_get): Environments - [POST /v1/projects/{project_id}/environments/{environment_id}/review-existing](/docs/api/operations/review_existing_environment_v1_projects__project_id__environments__environment_id__review_existing_post): Review Existing Environment - [POST /v1/projects/{project_id}/environments/{environment_id}/approve](/docs/api/operations/approve_environment_v1_projects__project_id__environments__environment_id__approve_post): Approve Environment - [POST /v1/projects/{project_id}/environments/{environment_id}/credential/reveal](/docs/api/operations/reveal_credential_v1_projects__project_id__environments__environment_id__credential_reveal_post): Reveal Credential - [GET /v1/projects/{project_id}/environments/{environment_id}/credential](/docs/api/operations/credential_status_v1_projects__project_id__environments__environment_id__credential_get): Credential Status - [POST /v1/projects/{project_id}/environments/{environment_id}/credential/rotate](/docs/api/operations/rotate_credential_v1_projects__project_id__environments__environment_id__credential_rotate_post): Rotate Credential - [POST /v1/institutions/{institution_id}/invitations/{invitation_id}/cancel](/docs/api/operations/cancel_invitation_v1_institutions__institution_id__invitations__invitation_id__cancel_post): Cancel Invitation - [POST /v1/institutions/{institution_id}/workflow-decisions/{kind}/{record_id}/reject](/docs/api/operations/reject_v1_institutions__institution_id__workflow_decisions__kind___record_id__reject_post): Reject - [GET /v1/institutions/{institution_id}/workflows](/docs/api/operations/institution_workflows_v1_institutions__institution_id__workflows_get): Institution Workflows - [GET /v1/institutions/{institution_id}/workflow-evidence/{kind}/{record_id}](/docs/api/operations/workflow_evidence_v1_institutions__institution_id__workflow_evidence__kind___record_id__get): Workflow Evidence - [GET /v1/projects/{project_id}/registration-context](/docs/api/operations/registration_context_v1_projects__project_id__registration_context_get): Registration Context - [GET /v1/projects/{project_id}/native-profiles](/docs/api/operations/native_profiles_v1_projects__project_id__native_profiles_get): Native Profiles - [GET /v1/me/workflows](/docs/api/operations/personal_workflows_v1_me_workflows_get): Personal Workflows ## GET /v1/registration-context Deployment Context Deployment Context Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters No path or query parameters declared. ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/registration-context' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/registration-context', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/registration-context', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/deployment_context_v1_registration_context_get) ## POST /v1/institutions/{institution_id}/administrators Propose Admin Propose Admin Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; AdministratorCreate | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `evidence_reference` | | string | Yes | Validation: min length 5; max length 500 | | `person_id` | | string | Yes | | ### Responses #### 201 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/administrators' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "evidence_reference": "REPLACE_WITH_EVIDENCE_REFERENCE", "person_id": "REPLACE_WITH_PERSON_ID" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/administrators', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "evidence_reference": "REPLACE_WITH_EVIDENCE_REFERENCE", "person_id": "REPLACE_WITH_PERSON_ID" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/administrators', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","evidence_reference":"REPLACE_WITH_EVIDENCE_REFERENCE","person_id":"REPLACE_WITH_PERSON_ID"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/propose_admin_v1_institutions__institution_id__administrators_post) ## POST /v1/institutions/{institution_id}/administrators/{proposal_id}/approve Approve Admin Approve Admin Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `proposal_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; Mutation | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/administrators/REPLACE_WITH_PROPOSAL_ID/approve' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/administrators/REPLACE_WITH_PROPOSAL_ID/approve', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/administrators/REPLACE_WITH_PROPOSAL_ID/approve', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/approve_admin_v1_institutions__institution_id__administrators__proposal_id__approve_post) ## POST /v1/institutions/{institution_id}/domains Propose Domain Propose Domain Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; DomainCreate | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `evidence_reference` | | string | Yes | Validation: min length 5; max length 500 | | `domain` | | string | Yes | Validation: min length 3; max length 253 | ### Responses #### 201 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/domains' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "evidence_reference": "REPLACE_WITH_EVIDENCE_REFERENCE", "domain": "REPLACE_WITH_DOMAIN" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/domains', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "evidence_reference": "REPLACE_WITH_EVIDENCE_REFERENCE", "domain": "REPLACE_WITH_DOMAIN" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/domains', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","evidence_reference":"REPLACE_WITH_EVIDENCE_REFERENCE","domain":"REPLACE_WITH_DOMAIN"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/propose_domain_v1_institutions__institution_id__domains_post) ## POST /v1/institutions/{institution_id}/domains/{domain_id}/verify Verify Domain Verify Domain Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `domain_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; Evidence | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `evidence_reference` | | string | Yes | Validation: min length 5; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/domains/REPLACE_WITH_DOMAIN_ID/verify' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "evidence_reference": "REPLACE_WITH_EVIDENCE_REFERENCE" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/domains/REPLACE_WITH_DOMAIN_ID/verify', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "evidence_reference": "REPLACE_WITH_EVIDENCE_REFERENCE" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/domains/REPLACE_WITH_DOMAIN_ID/verify', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","evidence_reference":"REPLACE_WITH_EVIDENCE_REFERENCE"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/verify_domain_v1_institutions__institution_id__domains__domain_id__verify_post) ## POST /v1/institutions/{institution_id}/sponsors Sponsor Change Sponsor Change Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; SponsorChange | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `evidence_reference` | | string | Yes | Validation: min length 5; max length 500 | | `person_id` | | string | Yes | | | `active` | | boolean | No | | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/sponsors' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "evidence_reference": "REPLACE_WITH_EVIDENCE_REFERENCE", "person_id": "REPLACE_WITH_PERSON_ID" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/sponsors', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "evidence_reference": "REPLACE_WITH_EVIDENCE_REFERENCE", "person_id": "REPLACE_WITH_PERSON_ID" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/sponsors', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","evidence_reference":"REPLACE_WITH_EVIDENCE_REFERENCE","person_id":"REPLACE_WITH_PERSON_ID"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/sponsor_change_v1_institutions__institution_id__sponsors_post) ## POST /v1/institutions/{institution_id}/invitations Invite Invite Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; InvitationCreate | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `recipient` | | string | Yes | Validation: min length 3; max length 254 | | `expires_in_hours` | | integer | No | Validation: minimum 1; maximum 168 | ### Responses #### 201 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/invitations' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "recipient": "REPLACE_WITH_RECIPIENT" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/invitations', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "recipient": "REPLACE_WITH_RECIPIENT" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/invitations', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","recipient":"REPLACE_WITH_RECIPIENT"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/invite_v1_institutions__institution_id__invitations_post) ## POST /v1/invitations/{invitation_id}/redeem Redeem Redeem Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `invitation_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; InvitationRedeem | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `secret` | | string | Yes | Validation: min length 32; max length 256 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/invitations/REPLACE_WITH_INVITATION_ID/redeem' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "secret": "REPLACE_WITH_SECRET" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/invitations/REPLACE_WITH_INVITATION_ID/redeem', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "secret": "REPLACE_WITH_SECRET" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/invitations/REPLACE_WITH_INVITATION_ID/redeem', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","secret":"REPLACE_WITH_SECRET"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/redeem_v1_invitations__invitation_id__redeem_post) ## POST /v1/institutions/{institution_id}/account-proofs Proof Proof Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; ProofCreate | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `evidence_reference` | | string | Yes | Validation: min length 5; max length 500 | | `project_id` | | string | Yes | | | `person_id` | | string | Yes | | | `local_account_id` | | string | Yes | Validation: min length 1; max length 200 | | `expires_in_minutes` | | integer | No | Validation: minimum 1; maximum 60 | ### Responses #### 201 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/account-proofs' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "evidence_reference": "REPLACE_WITH_EVIDENCE_REFERENCE", "project_id": "REPLACE_WITH_PROJECT_ID", "person_id": "REPLACE_WITH_PERSON_ID", "local_account_id": "REPLACE_WITH_LOCAL_ACCOUNT_ID" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/account-proofs', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "evidence_reference": "REPLACE_WITH_EVIDENCE_REFERENCE", "project_id": "REPLACE_WITH_PROJECT_ID", "person_id": "REPLACE_WITH_PERSON_ID", "local_account_id": "REPLACE_WITH_LOCAL_ACCOUNT_ID" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/account-proofs', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","evidence_reference":"REPLACE_WITH_EVIDENCE_REFERENCE","project_id":"REPLACE_WITH_PROJECT_ID","person_id":"REPLACE_WITH_PERSON_ID","local_account_id":"REPLACE_WITH_LOCAL_ACCOUNT_ID"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/proof_v1_institutions__institution_id__account_proofs_post) ## POST /v1/link-requests Request Link Request Link Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; LinkCreate | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `proof_id` | | string | Yes | | ### Responses #### 201 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/link-requests' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "proof_id": "REPLACE_WITH_PROOF_ID" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/link-requests', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "proof_id": "REPLACE_WITH_PROOF_ID" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/link-requests', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","proof_id":"REPLACE_WITH_PROOF_ID"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/request_link_v1_link_requests_post) ## POST /v1/link-requests/{request_id}/approve Approve Link Approve Link Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `request_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; Mutation | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/link-requests/REPLACE_WITH_REQUEST_ID/approve' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/link-requests/REPLACE_WITH_REQUEST_ID/approve', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/link-requests/REPLACE_WITH_REQUEST_ID/approve', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/approve_link_v1_link_requests__request_id__approve_post) ## POST /v1/institutions/{institution_id}/recovery-requests Recovery Recovery Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; RecoveryCreate | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `evidence_reference` | | string | Yes | Validation: min length 5; max length 500 | | `person_id` | | string | Yes | | ### Responses #### 201 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/recovery-requests' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "evidence_reference": "REPLACE_WITH_EVIDENCE_REFERENCE", "person_id": "REPLACE_WITH_PERSON_ID" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/recovery-requests', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "evidence_reference": "REPLACE_WITH_EVIDENCE_REFERENCE", "person_id": "REPLACE_WITH_PERSON_ID" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/recovery-requests', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","evidence_reference":"REPLACE_WITH_EVIDENCE_REFERENCE","person_id":"REPLACE_WITH_PERSON_ID"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/recovery_v1_institutions__institution_id__recovery_requests_post) ## POST /v1/recovery-requests/{request_id}/approve Approve Recovery Approve Recovery Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `request_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; Mutation | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/recovery-requests/REPLACE_WITH_REQUEST_ID/approve' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/recovery-requests/REPLACE_WITH_REQUEST_ID/approve', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/recovery-requests/REPLACE_WITH_REQUEST_ID/approve', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/approve_recovery_v1_recovery_requests__request_id__approve_post) ## POST /v1/projects/{project_id}/owners Owner Owner Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; OwnerChange | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `person_id` | | string | Yes | | | `active` | | boolean | No | | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/owners' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "person_id": "REPLACE_WITH_PERSON_ID" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/owners', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "person_id": "REPLACE_WITH_PERSON_ID" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/owners', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","person_id":"REPLACE_WITH_PERSON_ID"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/owner_v1_projects__project_id__owners_post) ## POST /v1/projects/{project_id}/environments Environment Environment Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; EnvironmentCreate | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `name` | | string | Yes | Validation: pattern ^(development\|staging\|production)$ | | `client_type` | | public \| confidential-web \| native-mail-ios \| native-mail-android \| native-mail-desktop | No | | | `redirect_uris` | | string[] | Yes | Validation: min items 1; max items 20 | | `scopes` | | string[] | No | Validation: min items 1; max items 10 | ### Responses #### 201 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/environments' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "name": "REPLACE_WITH_NAME", "redirect_uris": [] }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/environments', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "name": "REPLACE_WITH_NAME", "redirect_uris": [] }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/environments', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","name":"REPLACE_WITH_NAME","redirect_uris":[]}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/environment_v1_projects__project_id__environments_post) ## GET /v1/projects/{project_id}/environments Environments Environments Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/environments' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/environments', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/environments', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/environments_v1_projects__project_id__environments_get) ## POST /v1/projects/{project_id}/environments/{environment_id}/review-existing Review Existing Environment Review Existing Environment Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `environment_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; Mutation | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/environments/REPLACE_WITH_ENVIRONMENT_ID/review-existing' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/environments/REPLACE_WITH_ENVIRONMENT_ID/review-existing', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/environments/REPLACE_WITH_ENVIRONMENT_ID/review-existing', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/review_existing_environment_v1_projects__project_id__environments__environment_id__review_existing_post) ## POST /v1/projects/{project_id}/environments/{environment_id}/approve Approve Environment Approve Environment Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `environment_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; Mutation | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/environments/REPLACE_WITH_ENVIRONMENT_ID/approve' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/environments/REPLACE_WITH_ENVIRONMENT_ID/approve', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/environments/REPLACE_WITH_ENVIRONMENT_ID/approve', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/approve_environment_v1_projects__project_id__environments__environment_id__approve_post) ## POST /v1/projects/{project_id}/environments/{environment_id}/credential/reveal Reveal Credential Reveal Credential Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `environment_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; Mutation | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/environments/REPLACE_WITH_ENVIRONMENT_ID/credential/reveal' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/environments/REPLACE_WITH_ENVIRONMENT_ID/credential/reveal', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/environments/REPLACE_WITH_ENVIRONMENT_ID/credential/reveal', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/reveal_credential_v1_projects__project_id__environments__environment_id__credential_reveal_post) ## GET /v1/projects/{project_id}/environments/{environment_id}/credential Credential Status Credential Status Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `environment_id` | path | string | Yes | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/environments/REPLACE_WITH_ENVIRONMENT_ID/credential' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/environments/REPLACE_WITH_ENVIRONMENT_ID/credential', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/environments/REPLACE_WITH_ENVIRONMENT_ID/credential', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/credential_status_v1_projects__project_id__environments__environment_id__credential_get) ## POST /v1/projects/{project_id}/environments/{environment_id}/credential/rotate Rotate Credential Rotate Credential Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `environment_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; Mutation | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/environments/REPLACE_WITH_ENVIRONMENT_ID/credential/rotate' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/environments/REPLACE_WITH_ENVIRONMENT_ID/credential/rotate', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/environments/REPLACE_WITH_ENVIRONMENT_ID/credential/rotate', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/rotate_credential_v1_projects__project_id__environments__environment_id__credential_rotate_post) ## POST /v1/institutions/{institution_id}/invitations/{invitation_id}/cancel Cancel Invitation Cancel Invitation Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `invitation_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; Mutation | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/invitations/REPLACE_WITH_INVITATION_ID/cancel' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/invitations/REPLACE_WITH_INVITATION_ID/cancel', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/invitations/REPLACE_WITH_INVITATION_ID/cancel', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/cancel_invitation_v1_institutions__institution_id__invitations__invitation_id__cancel_post) ## POST /v1/institutions/{institution_id}/workflow-decisions/{kind}/{record_id}/reject Reject Reject Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `kind` | path | administrator \| domain \| link \| recovery \| federation | Yes | | | `record_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; Mutation | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/workflow-decisions/REPLACE_WITH_KIND/REPLACE_WITH_RECORD_ID/reject' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/workflow-decisions/REPLACE_WITH_KIND/REPLACE_WITH_RECORD_ID/reject', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/workflow-decisions/REPLACE_WITH_KIND/REPLACE_WITH_RECORD_ID/reject', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/reject_v1_institutions__institution_id__workflow_decisions__kind___record_id__reject_post) ## GET /v1/institutions/{institution_id}/workflows Institution Workflows Institution Workflows Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/workflows' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/workflows', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/workflows', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/institution_workflows_v1_institutions__institution_id__workflows_get) ## GET /v1/institutions/{institution_id}/workflow-evidence/{kind}/{record_id} Workflow Evidence Workflow Evidence Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `kind` | path | administrator \| domain \| federation \| recovery | Yes | | | `record_id` | path | string | Yes | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/workflow-evidence/REPLACE_WITH_KIND/REPLACE_WITH_RECORD_ID' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/workflow-evidence/REPLACE_WITH_KIND/REPLACE_WITH_RECORD_ID', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/workflow-evidence/REPLACE_WITH_KIND/REPLACE_WITH_RECORD_ID', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/workflow_evidence_v1_institutions__institution_id__workflow_evidence__kind___record_id__get) ## GET /v1/projects/{project_id}/registration-context Registration Context Registration Context Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/registration-context' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/registration-context', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/registration-context', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/registration_context_v1_projects__project_id__registration_context_get) ## GET /v1/projects/{project_id}/native-profiles Native Profiles Native Profiles Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/native-profiles' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/native-profiles', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/native-profiles', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/native_profiles_v1_projects__project_id__native_profiles_get) ## GET /v1/me/workflows Personal Workflows Personal Workflows Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters No path or query parameters declared. ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/me/workflows' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/me/workflows', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/me/workflows', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/personal_workflows_v1_me_workflows_get) --- # Staff enrollment 6 management API operations. - [GET /v1/institutions/{institution_id}/enrollments](/docs/api/operations/inventory_v1_institutions__institution_id__enrollments_get): Inventory - [POST /v1/institutions/{institution_id}/enrollments](/docs/api/operations/propose_v1_institutions__institution_id__enrollments_post): Propose - [GET /v1/institutions/{institution_id}/enrollments/{identifier}/review](/docs/api/operations/review_details_v1_institutions__institution_id__enrollments__identifier__review_get): Review Details - [POST /v1/institutions/{institution_id}/enrollments/{identifier}/refresh-review](/docs/api/operations/refresh_v1_institutions__institution_id__enrollments__identifier__refresh_review_post): Refresh - [POST /v1/institutions/{institution_id}/enrollments/{identifier}/approve](/docs/api/operations/approve_v1_institutions__institution_id__enrollments__identifier__approve_post): Approve - [POST /v1/institutions/{institution_id}/enrollments/{identifier}/cancel](/docs/api/operations/cancel_v1_institutions__institution_id__enrollments__identifier__cancel_post): Cancel ## GET /v1/institutions/{institution_id}/enrollments Inventory Inventory Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/enrollments' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/enrollments', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/enrollments', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/inventory_v1_institutions__institution_id__enrollments_get) ## POST /v1/institutions/{institution_id}/enrollments Propose Propose Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; EnrollmentCreate | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `recipient` | | string | Yes | Validation: min length 3; max length 254 | ### Responses #### 201 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/enrollments' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "recipient": "REPLACE_WITH_RECIPIENT" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/enrollments', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "recipient": "REPLACE_WITH_RECIPIENT" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/enrollments', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","recipient":"REPLACE_WITH_RECIPIENT"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/propose_v1_institutions__institution_id__enrollments_post) ## GET /v1/institutions/{institution_id}/enrollments/{identifier}/review Review Details Review Details Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `identifier` | path | string | Yes | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/enrollments/REPLACE_WITH_IDENTIFIER/review' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/enrollments/REPLACE_WITH_IDENTIFIER/review', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/enrollments/REPLACE_WITH_IDENTIFIER/review', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/review_details_v1_institutions__institution_id__enrollments__identifier__review_get) ## POST /v1/institutions/{institution_id}/enrollments/{identifier}/refresh-review Refresh Refresh Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `identifier` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; identity__enrollment_router__Reason | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/enrollments/REPLACE_WITH_IDENTIFIER/refresh-review' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/enrollments/REPLACE_WITH_IDENTIFIER/refresh-review', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/enrollments/REPLACE_WITH_IDENTIFIER/refresh-review', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/refresh_v1_institutions__institution_id__enrollments__identifier__refresh_review_post) ## POST /v1/institutions/{institution_id}/enrollments/{identifier}/approve Approve Approve Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `identifier` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; identity__enrollment_router__Reason | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/enrollments/REPLACE_WITH_IDENTIFIER/approve' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/enrollments/REPLACE_WITH_IDENTIFIER/approve', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/enrollments/REPLACE_WITH_IDENTIFIER/approve', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/approve_v1_institutions__institution_id__enrollments__identifier__approve_post) ## POST /v1/institutions/{institution_id}/enrollments/{identifier}/cancel Cancel Cancel Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `identifier` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; identity__enrollment_router__Reason | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/enrollments/REPLACE_WITH_IDENTIFIER/cancel' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/enrollments/REPLACE_WITH_IDENTIFIER/cancel', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/enrollments/REPLACE_WITH_IDENTIFIER/cancel', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/cancel_v1_institutions__institution_id__enrollments__identifier__cancel_post) --- # Standalone workforce admission 5 management API operations. - [GET /v1/institutions/{institution_id}/auth-engine-enrollments](/docs/api/operations/inventory_v1_institutions__institution_id__auth_engine_enrollments_get): Inventory - [POST /v1/institutions/{institution_id}/auth-engine-enrollments](/docs/api/operations/propose_v1_institutions__institution_id__auth_engine_enrollments_post): Propose - [GET /v1/institutions/{institution_id}/auth-engine-enrollments/{identifier}/review](/docs/api/operations/review_details_v1_institutions__institution_id__auth_engine_enrollments__identifier__review_get): Review Details - [POST /v1/institutions/{institution_id}/auth-engine-enrollments/{identifier}/approve](/docs/api/operations/approve_v1_institutions__institution_id__auth_engine_enrollments__identifier__approve_post): Approve - [POST /v1/institutions/{institution_id}/auth-engine-enrollments/{identifier}/cancel](/docs/api/operations/cancel_v1_institutions__institution_id__auth_engine_enrollments__identifier__cancel_post): Cancel ## GET /v1/institutions/{institution_id}/auth-engine-enrollments Inventory Inventory Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/auth-engine-enrollments' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/auth-engine-enrollments', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/auth-engine-enrollments', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/inventory_v1_institutions__institution_id__auth_engine_enrollments_get) ## POST /v1/institutions/{institution_id}/auth-engine-enrollments Propose Propose Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; FreshEnrollmentCreate | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `recipient` | | string | Yes | Validation: min length 3; max length 254 | ### Responses #### 201 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/auth-engine-enrollments' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "recipient": "REPLACE_WITH_RECIPIENT" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/auth-engine-enrollments', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "recipient": "REPLACE_WITH_RECIPIENT" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/auth-engine-enrollments', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","recipient":"REPLACE_WITH_RECIPIENT"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/propose_v1_institutions__institution_id__auth_engine_enrollments_post) ## GET /v1/institutions/{institution_id}/auth-engine-enrollments/{identifier}/review Review Details Review Details Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `identifier` | path | string | Yes | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/auth-engine-enrollments/REPLACE_WITH_IDENTIFIER/review' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/auth-engine-enrollments/REPLACE_WITH_IDENTIFIER/review', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/auth-engine-enrollments/REPLACE_WITH_IDENTIFIER/review', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/review_details_v1_institutions__institution_id__auth_engine_enrollments__identifier__review_get) ## POST /v1/institutions/{institution_id}/auth-engine-enrollments/{identifier}/approve Approve Approve Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `identifier` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; identity__auth_engine_enrollment_router__Reason | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/auth-engine-enrollments/REPLACE_WITH_IDENTIFIER/approve' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/auth-engine-enrollments/REPLACE_WITH_IDENTIFIER/approve', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/auth-engine-enrollments/REPLACE_WITH_IDENTIFIER/approve', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/approve_v1_institutions__institution_id__auth_engine_enrollments__identifier__approve_post) ## POST /v1/institutions/{institution_id}/auth-engine-enrollments/{identifier}/cancel Cancel Cancel Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `identifier` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; identity__auth_engine_enrollment_router__Reason | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/auth-engine-enrollments/REPLACE_WITH_IDENTIFIER/cancel' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/auth-engine-enrollments/REPLACE_WITH_IDENTIFIER/cancel', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/auth-engine-enrollments/REPLACE_WITH_IDENTIFIER/cancel', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/cancel_v1_institutions__institution_id__auth_engine_enrollments__identifier__cancel_post) --- # Personal sessions 2 management API operations. - [POST /v1/me/sessions/revoke-all](/docs/api/operations/revoke_all_v1_me_sessions_revoke_all_post): Revoke All - [POST /v1/me/sessions/{session_id}/revoke](/docs/api/operations/revoke_session_v1_me_sessions__session_id__revoke_post): Revoke Session ## POST /v1/me/sessions/revoke-all Revoke All Revoke All Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; Mutation | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/me/sessions/revoke-all' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/me/sessions/revoke-all', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/me/sessions/revoke-all', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/revoke_all_v1_me_sessions_revoke_all_post) ## POST /v1/me/sessions/{session_id}/revoke Revoke Session Revoke Session Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `session_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; Mutation | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/me/sessions/REPLACE_WITH_SESSION_ID/revoke' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/me/sessions/REPLACE_WITH_SESSION_ID/revoke', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/me/sessions/REPLACE_WITH_SESSION_ID/revoke', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/revoke_session_v1_me_sessions__session_id__revoke_post) --- # Account linking 9 management API operations. - [POST /v1/link-challenges](/docs/api/operations/create_challenge_v1_link_challenges_post): Create Challenge - [GET /v1/link-challenges/{challenge_id}](/docs/api/operations/read_challenge_v1_link_challenges__challenge_id__get): Read Challenge - [POST /v1/link-challenges/{challenge_id}/attest](/docs/api/operations/attest_v1_link_challenges__challenge_id__attest_post): Attest - [GET /v1/link-requests/{link_id}](/docs/api/operations/read_link_v1_link_requests__link_id__get): Read Link - [POST /v1/link-requests/{link_id}/ack](/docs/api/operations/acknowledge_v1_link_requests__link_id__ack_post): Acknowledge - [GET /v1/projects/{project_id}/service-identities](/docs/api/operations/read_services_v1_projects__project_id__service_identities_get): Read Services - [POST /v1/projects/{project_id}/service-identities](/docs/api/operations/propose_service_v1_projects__project_id__service_identities_post): Propose Service - [POST /v1/projects/{project_id}/service-identities/{grant_id}/approve](/docs/api/operations/approve_service_v1_projects__project_id__service_identities__grant_id__approve_post): Approve Service - [POST /v1/projects/{project_id}/service-identities/{grant_id}/revoke](/docs/api/operations/revoke_service_v1_projects__project_id__service_identities__grant_id__revoke_post): Revoke Service ## POST /v1/link-challenges Create Challenge Create Challenge Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; ChallengeCreate | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `project_id` | | string | Yes | | | `institution_id` | | string | Yes | | ### Responses #### 201 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/link-challenges' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "project_id": "REPLACE_WITH_PROJECT_ID", "institution_id": "REPLACE_WITH_INSTITUTION_ID" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/link-challenges', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "project_id": "REPLACE_WITH_PROJECT_ID", "institution_id": "REPLACE_WITH_INSTITUTION_ID" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/link-challenges', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","project_id":"REPLACE_WITH_PROJECT_ID","institution_id":"REPLACE_WITH_INSTITUTION_ID"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/create_challenge_v1_link_challenges_post) ## GET /v1/link-challenges/{challenge_id} Read Challenge Read Challenge Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `challenge_id` | path | string | Yes | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/link-challenges/REPLACE_WITH_CHALLENGE_ID' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/link-challenges/REPLACE_WITH_CHALLENGE_ID', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/link-challenges/REPLACE_WITH_CHALLENGE_ID', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/read_challenge_v1_link_challenges__challenge_id__get) ## POST /v1/link-challenges/{challenge_id}/attest Attest Attest Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `challenge_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; Attestation | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `local_account_id` | | string | Yes | Validation: min length 1; max length 200 | | `local_auth_time` | | integer | Yes | | | `local_auth_method` | | string | Yes | Validation: min length 1; max length 100 | | `local_session_digest` | | string | Yes | Validation: pattern ^[0-9a-f]{64}$ | | `central_issuer` | | string | Yes | | | `central_subject` | | string | Yes | | | `central_auth_time` | | integer | Yes | | | `central_acr` | | taifa-mfa \| taifa-phishing-resistant | Yes | | | `central_sid_digest` | | string | Yes | Validation: pattern ^[0-9a-f]{64}$ | ### Responses #### 201 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/link-challenges/REPLACE_WITH_CHALLENGE_ID/attest' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "local_account_id": "REPLACE_WITH_LOCAL_ACCOUNT_ID", "local_auth_time": 0, "local_auth_method": "REPLACE_WITH_LOCAL_AUTH_METHOD", "local_session_digest": "REPLACE_WITH_LOCAL_SESSION_DIGEST", "central_issuer": "REPLACE_WITH_CENTRAL_ISSUER", "central_subject": "REPLACE_WITH_CENTRAL_SUBJECT", "central_auth_time": 0, "central_acr": "REPLACE_WITH_CENTRAL_ACR", "central_sid_digest": "REPLACE_WITH_CENTRAL_SID_DIGEST" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/link-challenges/REPLACE_WITH_CHALLENGE_ID/attest', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "local_account_id": "REPLACE_WITH_LOCAL_ACCOUNT_ID", "local_auth_time": 0, "local_auth_method": "REPLACE_WITH_LOCAL_AUTH_METHOD", "local_session_digest": "REPLACE_WITH_LOCAL_SESSION_DIGEST", "central_issuer": "REPLACE_WITH_CENTRAL_ISSUER", "central_subject": "REPLACE_WITH_CENTRAL_SUBJECT", "central_auth_time": 0, "central_acr": "REPLACE_WITH_CENTRAL_ACR", "central_sid_digest": "REPLACE_WITH_CENTRAL_SID_DIGEST" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/link-challenges/REPLACE_WITH_CHALLENGE_ID/attest', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","local_account_id":"REPLACE_WITH_LOCAL_ACCOUNT_ID","local_auth_time":0,"local_auth_method":"REPLACE_WITH_LOCAL_AUTH_METHOD","local_session_digest":"REPLACE_WITH_LOCAL_SESSION_DIGEST","central_issuer":"REPLACE_WITH_CENTRAL_ISSUER","central_subject":"REPLACE_WITH_CENTRAL_SUBJECT","central_auth_time":0,"central_acr":"REPLACE_WITH_CENTRAL_ACR","central_sid_digest":"REPLACE_WITH_CENTRAL_SID_DIGEST"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/attest_v1_link_challenges__challenge_id__attest_post) ## GET /v1/link-requests/{link_id} Read Link Read Link Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `link_id` | path | string | Yes | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/link-requests/REPLACE_WITH_LINK_ID' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/link-requests/REPLACE_WITH_LINK_ID', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/link-requests/REPLACE_WITH_LINK_ID', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/read_link_v1_link_requests__link_id__get) ## POST /v1/link-requests/{link_id}/ack Acknowledge Acknowledge Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `link_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; BindingAcknowledgement | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `entity_id` | | string | Yes | | | `entity_version` | | integer | Yes | Validation: minimum 1 | | `local_account_id` | | string | Yes | | | `proof_id` | | string | Yes | | | `approval_id` | | string | Yes | | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/link-requests/REPLACE_WITH_LINK_ID/ack' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "entity_id": "REPLACE_WITH_ENTITY_ID", "entity_version": 0, "local_account_id": "REPLACE_WITH_LOCAL_ACCOUNT_ID", "proof_id": "REPLACE_WITH_PROOF_ID", "approval_id": "REPLACE_WITH_APPROVAL_ID" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/link-requests/REPLACE_WITH_LINK_ID/ack', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "entity_id": "REPLACE_WITH_ENTITY_ID", "entity_version": 0, "local_account_id": "REPLACE_WITH_LOCAL_ACCOUNT_ID", "proof_id": "REPLACE_WITH_PROOF_ID", "approval_id": "REPLACE_WITH_APPROVAL_ID" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/link-requests/REPLACE_WITH_LINK_ID/ack', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","entity_id":"REPLACE_WITH_ENTITY_ID","entity_version":0,"local_account_id":"REPLACE_WITH_LOCAL_ACCOUNT_ID","proof_id":"REPLACE_WITH_PROOF_ID","approval_id":"REPLACE_WITH_APPROVAL_ID"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/acknowledge_v1_link_requests__link_id__ack_post) ## GET /v1/projects/{project_id}/service-identities Read Services Read Services Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/service-identities' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/service-identities', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/service-identities', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/read_services_v1_projects__project_id__service_identities_get) ## POST /v1/projects/{project_id}/service-identities Propose Service Propose Service Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; ServiceProposal | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `issuer` | | string | Yes | | | `subject` | | string | Yes | Validation: min length 1; max length 255 | | `capability` | | account-link-attestor | Yes | | ### Responses #### 201 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/service-identities' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "issuer": "REPLACE_WITH_ISSUER", "subject": "REPLACE_WITH_SUBJECT", "capability": "REPLACE_WITH_CAPABILITY" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/service-identities', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "issuer": "REPLACE_WITH_ISSUER", "subject": "REPLACE_WITH_SUBJECT", "capability": "REPLACE_WITH_CAPABILITY" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/service-identities', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","issuer":"REPLACE_WITH_ISSUER","subject":"REPLACE_WITH_SUBJECT","capability":"REPLACE_WITH_CAPABILITY"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/propose_service_v1_projects__project_id__service_identities_post) ## POST /v1/projects/{project_id}/service-identities/{grant_id}/approve Approve Service Approve Service Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `grant_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; Mutation | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/service-identities/REPLACE_WITH_GRANT_ID/approve' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/service-identities/REPLACE_WITH_GRANT_ID/approve', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/service-identities/REPLACE_WITH_GRANT_ID/approve', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/approve_service_v1_projects__project_id__service_identities__grant_id__approve_post) ## POST /v1/projects/{project_id}/service-identities/{grant_id}/revoke Revoke Service Revoke Service Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `grant_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; Mutation | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/service-identities/REPLACE_WITH_GRANT_ID/revoke' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/service-identities/REPLACE_WITH_GRANT_ID/revoke', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/service-identities/REPLACE_WITH_GRANT_ID/revoke', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/revoke_service_v1_projects__project_id__service_identities__grant_id__revoke_post) --- # Security incident sessions 3 management API operations. - [GET /v1/security/people](/docs/api/operations/identities_v1_security_people_get): Identities - [GET /v1/people/{person_id}/sessions](/docs/api/operations/sessions_v1_people__person_id__sessions_get): Sessions - [POST /v1/people/{person_id}/sessions/{session_id}/revoke](/docs/api/operations/revoke_v1_people__person_id__sessions__session_id__revoke_post): Revoke ## GET /v1/security/people Identities Identities Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `subject` | query | string | No | Validation: max length 200 | ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/security/people' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/security/people', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/security/people', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/identities_v1_security_people_get) ## GET /v1/people/{person_id}/sessions Sessions Sessions Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `person_id` | path | string | Yes | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/people/REPLACE_WITH_PERSON_ID/sessions' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/people/REPLACE_WITH_PERSON_ID/sessions', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/people/REPLACE_WITH_PERSON_ID/sessions', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/sessions_v1_people__person_id__sessions_get) ## POST /v1/people/{person_id}/sessions/{session_id}/revoke Revoke Revoke Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `person_id` | path | string | Yes | | | `session_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; Mutation | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/people/REPLACE_WITH_PERSON_ID/sessions/REPLACE_WITH_SESSION_ID/revoke' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/people/REPLACE_WITH_PERSON_ID/sessions/REPLACE_WITH_SESSION_ID/revoke', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/people/REPLACE_WITH_PERSON_ID/sessions/REPLACE_WITH_SESSION_ID/revoke', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/revoke_v1_people__person_id__sessions__session_id__revoke_post) --- # Reviewed authentication policy 4 management API operations. - [GET /v1/policies](/docs/api/operations/policies_v1_policies_get): Policies - [POST /v1/policies/reviews](/docs/api/operations/propose_v1_policies_reviews_post): Propose - [POST /v1/policies/reviews/{review_id}/approve](/docs/api/operations/approve_v1_policies_reviews__review_id__approve_post): Approve - [POST /v1/policies/reviews/{review_id}/reconcile](/docs/api/operations/reconcile_v1_policies_reviews__review_id__reconcile_post): Reconcile ## GET /v1/policies Policies Policies Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters No path or query parameters declared. ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/policies' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/policies', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/policies', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/policies_v1_policies_get) ## POST /v1/policies/reviews Propose Propose Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; Proposal | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `accessTokenLifespan` | | integer | Yes | Validation: minimum 60; maximum 3600 | | `ssoSessionIdleTimeout` | | integer | Yes | Validation: minimum 60; maximum 28800 | | `ssoSessionMaxLifespan` | | integer | Yes | Validation: minimum 300; maximum 86400 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/policies/reviews' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "accessTokenLifespan": 0, "ssoSessionIdleTimeout": 0, "ssoSessionMaxLifespan": 0 }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/policies/reviews', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "accessTokenLifespan": 0, "ssoSessionIdleTimeout": 0, "ssoSessionMaxLifespan": 0 }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/policies/reviews', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","accessTokenLifespan":0,"ssoSessionIdleTimeout":0,"ssoSessionMaxLifespan":0}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/propose_v1_policies_reviews_post) ## POST /v1/policies/reviews/{review_id}/approve Approve Approve Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `review_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; Approval | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `role` | | string | Yes | | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/policies/reviews/REPLACE_WITH_REVIEW_ID/approve' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "role": "REPLACE_WITH_ROLE" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/policies/reviews/REPLACE_WITH_REVIEW_ID/approve', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "role": "REPLACE_WITH_ROLE" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/policies/reviews/REPLACE_WITH_REVIEW_ID/approve', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","role":"REPLACE_WITH_ROLE"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/approve_v1_policies_reviews__review_id__approve_post) ## POST /v1/policies/reviews/{review_id}/reconcile Reconcile Reconcile Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `review_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; Mutation | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/policies/reviews/REPLACE_WITH_REVIEW_ID/reconcile' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/policies/reviews/REPLACE_WITH_REVIEW_ID/reconcile', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/policies/reviews/REPLACE_WITH_REVIEW_ID/reconcile', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/reconcile_v1_policies_reviews__review_id__reconcile_post) --- # Operations 4 management API operations. - [GET /v1/operations/diagnostics](/docs/api/operations/diagnostics_v1_operations_diagnostics_get): Diagnostics - [GET /v1/projects/{project_id}/diagnostics](/docs/api/operations/project_diagnostics_v1_projects__project_id__diagnostics_get): Project Diagnostics - [POST /v1/projects/{project_id}/diagnostics/clients/{environment_id}](/docs/api/operations/check_client_v1_projects__project_id__diagnostics_clients__environment_id__post): Check Client - [POST /v1/jobs/{job_id}/review](/docs/api/operations/review_job_v1_jobs__job_id__review_post): Review Job ## GET /v1/operations/diagnostics Diagnostics Diagnostics Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters No path or query parameters declared. ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/operations/diagnostics' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/operations/diagnostics', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/operations/diagnostics', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/diagnostics_v1_operations_diagnostics_get) ## GET /v1/projects/{project_id}/diagnostics Project Diagnostics Project Diagnostics Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/diagnostics' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/diagnostics', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/diagnostics', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/project_diagnostics_v1_projects__project_id__diagnostics_get) ## POST /v1/projects/{project_id}/diagnostics/clients/{environment_id} Check Client Check Client Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `environment_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; ClientCheck | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/diagnostics/clients/REPLACE_WITH_ENVIRONMENT_ID' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/diagnostics/clients/REPLACE_WITH_ENVIRONMENT_ID', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/diagnostics/clients/REPLACE_WITH_ENVIRONMENT_ID', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/check_client_v1_projects__project_id__diagnostics_clients__environment_id__post) ## POST /v1/jobs/{job_id}/review Review Job Review Job Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `job_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; JobReview | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `expected_status` | | failed \| ambiguous | Yes | | | `action` | | retry \| reconcile | Yes | | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/jobs/REPLACE_WITH_JOB_ID/review' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "expected_status": "REPLACE_WITH_EXPECTED_STATUS", "action": "REPLACE_WITH_ACTION", "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/jobs/REPLACE_WITH_JOB_ID/review', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "expected_status": "REPLACE_WITH_EXPECTED_STATUS", "action": "REPLACE_WITH_ACTION", "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/jobs/REPLACE_WITH_JOB_ID/review', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"expected_status":"REPLACE_WITH_EXPECTED_STATUS","action":"REPLACE_WITH_ACTION","reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/review_job_v1_jobs__job_id__review_post) --- # Personal capabilities 14 management API operations. - [POST /v1/projects/{project_id}/launch-proposals](/docs/api/operations/launch_v1_projects__project_id__launch_proposals_post): Launch - [GET /v1/projects/{project_id}/launch-proposals](/docs/api/operations/launch_proposals_v1_projects__project_id__launch_proposals_get): Launch Proposals - [POST /v1/projects/{project_id}/launch-proposals/{proposal_id}/approve](/docs/api/operations/approve_launch_v1_projects__project_id__launch_proposals__proposal_id__approve_post): Approve Launch - [GET /v1/me/apps](/docs/api/operations/apps_v1_me_apps_get): Apps - [GET /v1/me/access-requests](/docs/api/operations/requests_v1_me_access_requests_get): Requests - [POST /v1/me/access-requests](/docs/api/operations/request_v1_me_access_requests_post): Request - [GET /v1/institutions/{institution_id}/access-requests](/docs/api/operations/queue_v1_institutions__institution_id__access_requests_get): Queue - [POST /v1/institutions/{institution_id}/access-requests/{request_id}/endorse](/docs/api/operations/endorse_v1_institutions__institution_id__access_requests__request_id__endorse_post): Endorse - [POST /v1/institutions/{institution_id}/access-requests/{request_id}/approve](/docs/api/operations/approve_request_v1_institutions__institution_id__access_requests__request_id__approve_post): Approve Request - [GET /v1/me/provider-account](/docs/api/operations/provider_account_v1_me_provider_account_get): Provider Account - [GET /v1/me/authentication-activity](/docs/api/operations/authentication_activity_v1_me_authentication_activity_get): Authentication Activity - [GET /v1/me/security-activity](/docs/api/operations/activity_v1_me_security_activity_get): Activity - [GET /v1/me/consents](/docs/api/operations/consents_v1_me_consents_get): Consents - [POST /v1/me/consents/{client_id}/revoke](/docs/api/operations/revoke_consent_v1_me_consents__client_id__revoke_post): Revoke Consent ## POST /v1/projects/{project_id}/launch-proposals Launch Launch Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; LaunchCreate | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `launch_url` | | string | Yes | Validation: max length 2048 | ### Responses #### 201 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/launch-proposals' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "launch_url": "REPLACE_WITH_LAUNCH_URL" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/launch-proposals', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "launch_url": "REPLACE_WITH_LAUNCH_URL" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/launch-proposals', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","launch_url":"REPLACE_WITH_LAUNCH_URL"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/launch_v1_projects__project_id__launch_proposals_post) ## GET /v1/projects/{project_id}/launch-proposals Launch Proposals Launch Proposals Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/launch-proposals' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/launch-proposals', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/launch-proposals', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/launch_proposals_v1_projects__project_id__launch_proposals_get) ## POST /v1/projects/{project_id}/launch-proposals/{proposal_id}/approve Approve Launch Approve Launch Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `proposal_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; identity__personal_capabilities__Reason | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/launch-proposals/REPLACE_WITH_PROPOSAL_ID/approve' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/launch-proposals/REPLACE_WITH_PROPOSAL_ID/approve', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/launch-proposals/REPLACE_WITH_PROPOSAL_ID/approve', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/approve_launch_v1_projects__project_id__launch_proposals__proposal_id__approve_post) ## GET /v1/me/apps Apps Apps Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters No path or query parameters declared. ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/me/apps' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/me/apps', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/me/apps', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/apps_v1_me_apps_get) ## GET /v1/me/access-requests Requests Requests Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters No path or query parameters declared. ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/me/access-requests' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/me/access-requests', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/me/access-requests', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/requests_v1_me_access_requests_get) ## POST /v1/me/access-requests Request Request Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; RequestCreate | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `institution_id` | | string | Yes | | | `project_id` | | string | Yes | | ### Responses #### 201 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/me/access-requests' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "institution_id": "REPLACE_WITH_INSTITUTION_ID", "project_id": "REPLACE_WITH_PROJECT_ID" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/me/access-requests', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "institution_id": "REPLACE_WITH_INSTITUTION_ID", "project_id": "REPLACE_WITH_PROJECT_ID" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/me/access-requests', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","institution_id":"REPLACE_WITH_INSTITUTION_ID","project_id":"REPLACE_WITH_PROJECT_ID"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/request_v1_me_access_requests_post) ## GET /v1/institutions/{institution_id}/access-requests Queue Queue Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/access-requests' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/access-requests', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/access-requests', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/queue_v1_institutions__institution_id__access_requests_get) ## POST /v1/institutions/{institution_id}/access-requests/{request_id}/endorse Endorse Endorse Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `request_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; identity__personal_capabilities__Reason | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/access-requests/REPLACE_WITH_REQUEST_ID/endorse' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/access-requests/REPLACE_WITH_REQUEST_ID/endorse', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/access-requests/REPLACE_WITH_REQUEST_ID/endorse', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/endorse_v1_institutions__institution_id__access_requests__request_id__endorse_post) ## POST /v1/institutions/{institution_id}/access-requests/{request_id}/approve Approve Request Approve Request Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `institution_id` | path | string | Yes | | | `request_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; identity__personal_capabilities__Reason | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/access-requests/REPLACE_WITH_REQUEST_ID/approve' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/access-requests/REPLACE_WITH_REQUEST_ID/approve', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/institutions/REPLACE_WITH_INSTITUTION_ID/access-requests/REPLACE_WITH_REQUEST_ID/approve', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/approve_request_v1_institutions__institution_id__access_requests__request_id__approve_post) ## GET /v1/me/provider-account Provider Account Provider Account Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters No path or query parameters declared. ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/me/provider-account' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/me/provider-account', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/me/provider-account', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/provider_account_v1_me_provider_account_get) ## GET /v1/me/authentication-activity Authentication Activity Authentication Activity Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters No path or query parameters declared. ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/me/authentication-activity' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/me/authentication-activity', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/me/authentication-activity', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/authentication_activity_v1_me_authentication_activity_get) ## GET /v1/me/security-activity Activity Activity Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters No path or query parameters declared. ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/me/security-activity' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/me/security-activity', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/me/security-activity', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/activity_v1_me_security_activity_get) ## GET /v1/me/consents Consents Consents Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters No path or query parameters declared. ### Request body This operation has no request body. ### Responses #### 200 Successful Response No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/me/consents' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/me/consents', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/me/consents', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/consents_v1_me_consents_get) ## POST /v1/me/consents/{client_id}/revoke Revoke Consent Revoke Consent Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `client_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; identity__personal_capabilities__Reason | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/me/consents/REPLACE_WITH_CLIENT_ID/revoke' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/me/consents/REPLACE_WITH_CLIENT_ID/revoke', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/me/consents/REPLACE_WITH_CLIENT_ID/revoke', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/revoke_consent_v1_me_consents__client_id__revoke_post) --- # Reviewed project clients 8 management API operations. - [GET /v1/projects/{project_id}/permission-catalogs](/docs/api/operations/catalogs_v1_projects__project_id__permission_catalogs_get): List reviewed permission catalogs - [POST /v1/projects/{project_id}/permission-catalogs](/docs/api/operations/catalog_propose_v1_projects__project_id__permission_catalogs_post): Propose an immutable permission catalog - [POST /v1/projects/{project_id}/permission-catalogs/{catalog_id}/approve](/docs/api/operations/catalog_approve_v1_projects__project_id__permission_catalogs__catalog_id__approve_post): Independently approve a catalog - [POST /v1/projects/{project_id}/permission-catalogs/{catalog_id}/revoke](/docs/api/operations/catalog_revoke_v1_projects__project_id__permission_catalogs__catalog_id__revoke_post): Revoke an approved catalog - [GET /v1/projects/{project_id}/owned-clients](/docs/api/operations/clients_v1_projects__project_id__owned_clients_get): List reviewed owned-client proposals - [POST /v1/projects/{project_id}/owned-clients](/docs/api/operations/client_propose_v1_projects__project_id__owned_clients_post): Propose an exact owned-client registration policy - [POST /v1/projects/{project_id}/owned-clients/{policy_id}/approve](/docs/api/operations/client_approve_v1_projects__project_id__owned_clients__policy_id__approve_post): Independently approve an owned-client proposal - [POST /v1/projects/{project_id}/owned-clients/{policy_id}/revoke](/docs/api/operations/client_revoke_v1_projects__project_id__owned_clients__policy_id__revoke_post): Revoke an owned-client proposal ## GET /v1/projects/{project_id}/permission-catalogs List reviewed permission catalogs List reviewed permission catalogs Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `catalogs` | | CatalogRead[] | Yes | | | `_actions` | | catalog-propose[] | Yes | | #### 403 Current project authority or independent review required No fields declared in the current specification. #### 409 Current exact proposal, catalog, version or idempotency conflict No fields declared in the current specification. #### 413 Exact JSON request exceeds 64 KiB No fields declared in the current specification. #### 422 Invalid exact reviewed policy or registration No fields declared in the current specification. #### 503 Configured owned issuer authority unavailable No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/permission-catalogs' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/permission-catalogs', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/permission-catalogs', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/catalogs_v1_projects__project_id__permission_catalogs_get) ## POST /v1/projects/{project_id}/permission-catalogs Propose an immutable permission catalog Current project owner proposes a versioned catalog. A separate current platform project approver must approve it. Idempotency-Key replays the exact actor and body. Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; CatalogProposal | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `permissions` | | Permission[] | Yes | Validation: min items 1; max items 32 | ### Responses #### 201 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | | string | Yes | | | `project_id` | | string | Yes | | | `revision` | | integer | Yes | | | `permissions` | | Permission[] | Yes | | | `digest` | | string | Yes | | | `status` | | pending_review \| approved \| superseded \| revoked | Yes | | | `proposer` | | string | Yes | | | `approver` | | string \| null | Yes | | | `created_at` | | string | Yes | | | `expires_at` | | string | Yes | | | `actions` | | (approve \| revoke)[] | Yes | | | `revocations` | | RevocationRead[] | No | | #### 403 Current project authority or independent review required No fields declared in the current specification. #### 409 Current exact proposal, catalog, version or idempotency conflict No fields declared in the current specification. #### 413 Exact JSON request exceeds 64 KiB No fields declared in the current specification. #### 422 Invalid exact reviewed policy or registration No fields declared in the current specification. #### 503 Configured owned issuer authority unavailable No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/permission-catalogs' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "permissions": [ { "description": "Read assigned case records", "id": "case.read" } ], "reason": "Define reviewed case access permissions" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/permission-catalogs', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "permissions": [ { "description": "Read assigned case records", "id": "case.read" } ], "reason": "Define reviewed case access permissions" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/permission-catalogs', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"permissions":[{"description":"Read assigned case records","id":"case.read"}],"reason":"Define reviewed case access permissions"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/catalog_propose_v1_projects__project_id__permission_catalogs_post) ## POST /v1/projects/{project_id}/permission-catalogs/{catalog_id}/approve Independently approve a catalog Independently approve a catalog Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `catalog_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; identity__owned_client_router__Reason | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | | string | Yes | | | `project_id` | | string | Yes | | | `revision` | | integer | Yes | | | `permissions` | | Permission[] | Yes | | | `digest` | | string | Yes | | | `status` | | pending_review \| approved \| superseded \| revoked | Yes | | | `proposer` | | string | Yes | | | `approver` | | string \| null | Yes | | | `created_at` | | string | Yes | | | `expires_at` | | string | Yes | | | `actions` | | (approve \| revoke)[] | Yes | | | `revocations` | | RevocationRead[] | No | | #### 403 Current project authority or independent review required No fields declared in the current specification. #### 409 Current exact proposal, catalog, version or idempotency conflict No fields declared in the current specification. #### 413 Exact JSON request exceeds 64 KiB No fields declared in the current specification. #### 422 Invalid exact reviewed policy or registration No fields declared in the current specification. #### 503 Configured owned issuer authority unavailable No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/permission-catalogs/REPLACE_WITH_CATALOG_ID/approve' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/permission-catalogs/REPLACE_WITH_CATALOG_ID/approve', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/permission-catalogs/REPLACE_WITH_CATALOG_ID/approve', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/catalog_approve_v1_projects__project_id__permission_catalogs__catalog_id__approve_post) ## POST /v1/projects/{project_id}/permission-catalogs/{catalog_id}/revoke Revoke an approved catalog Revoke an approved catalog Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `catalog_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; identity__owned_client_router__Reason | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | | string | Yes | | | `project_id` | | string | Yes | | | `revision` | | integer | Yes | | | `permissions` | | Permission[] | Yes | | | `digest` | | string | Yes | | | `status` | | pending_review \| approved \| superseded \| revoked | Yes | | | `proposer` | | string | Yes | | | `approver` | | string \| null | Yes | | | `created_at` | | string | Yes | | | `expires_at` | | string | Yes | | | `actions` | | (approve \| revoke)[] | Yes | | | `revocations` | | RevocationRead[] | No | | #### 403 Current project authority or independent review required No fields declared in the current specification. #### 409 Current exact proposal, catalog, version or idempotency conflict No fields declared in the current specification. #### 413 Exact JSON request exceeds 64 KiB No fields declared in the current specification. #### 422 Invalid exact reviewed policy or registration No fields declared in the current specification. #### 503 Configured owned issuer authority unavailable No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/permission-catalogs/REPLACE_WITH_CATALOG_ID/revoke' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/permission-catalogs/REPLACE_WITH_CATALOG_ID/revoke', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/permission-catalogs/REPLACE_WITH_CATALOG_ID/revoke', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/catalog_revoke_v1_projects__project_id__permission_catalogs__catalog_id__revoke_post) ## GET /v1/projects/{project_id}/owned-clients List reviewed owned-client proposals List reviewed owned-client proposals Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `clients` | | ClientRead[] | Yes | | | `_actions` | | client-propose[] | Yes | | #### 403 Current project authority or independent review required No fields declared in the current specification. #### 409 Current exact proposal, catalog, version or idempotency conflict No fields declared in the current specification. #### 413 Exact JSON request exceeds 64 KiB No fields declared in the current specification. #### 422 Invalid exact reviewed policy or registration No fields declared in the current specification. #### 503 Configured owned issuer authority unavailable No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/owned-clients' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/owned-clients', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/owned-clients', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/clients_v1_projects__project_id__owned_clients_get) ## POST /v1/projects/{project_id}/owned-clients Propose an exact owned-client registration policy Requires a controlled credential preparation and fresh private issuer custody readback. Stores the full immutable registration and versioned digest with exact accepted owner and catalog evidence for independent review. Approval does not install a client or authorize an assignment. Idempotency-Key replays the exact actor and body after current authority and fresh custody checks. Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; ClientProposal | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | | `target_issuer` | | string | Yes | Validation: min length 1; max length 2048 | | `client_id` | | string | Yes | Validation: min length 1; max length 128 | | `client_version` | | integer | Yes | Validation: minimum 1; maximum 9223372036854775807 | | `display_name` | | string | Yes | Validation: min length 3; max length 120 | | `catalog_id` | | string | Yes | Validation: min length 1; max length 200 | | `credential_preparation_id` | | string | Yes | Canonical preparation UUID from controlled credential delivery. Management verifies fresh private issuer readback; browser proof is reference metadata only. Validation: min length 36; max length 36 | | `permission_ids` | | string[] | Yes | Validation: min items 1; max items 32 | | `registration` | | RegistrationProposal | Yes | | ### Responses #### 201 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | | string | Yes | | | `project_id` | | string | Yes | | | `target_issuer` | | string | Yes | | | `client_id` | | string | Yes | | | `client_version` | | integer | Yes | | | `generation` | | integer | Yes | | | `display_name` | | string | Yes | | | `catalog_id` | | string | Yes | | | `catalog_digest` | | string | Yes | | | `permission_ids` | | string[] | Yes | | | `registration` | | RegistrationRead | Yes | | | `registration_digest` | | string | Yes | | | `policy_digest` | | string | Yes | | | `credential_preparation_id` | | string \| null | No | | | `custody_binding_digest` | | string \| null | No | | | `status` | | pending_review \| approved_pending_readback \| superseded \| revoked | Yes | | | `proposer` | | string | Yes | | | `approver` | | string \| null | Yes | | | `created_at` | | string | Yes | | | `expires_at` | | string | Yes | | | `actions` | | (approve \| revoke)[] | Yes | | | `revocation` | | RevocationRead \| null | No | | #### 403 Current project authority or independent review required No fields declared in the current specification. #### 409 Current exact proposal, catalog, version or idempotency conflict No fields declared in the current specification. #### 413 Exact JSON request exceeds 64 KiB No fields declared in the current specification. #### 422 Invalid exact reviewed policy or registration No fields declared in the current specification. #### 503 Configured owned issuer authority unavailable No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/owned-clients' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "catalog_id": "00000000-0000-4000-8000-000000000001", "client_id": "case-app-test", "client_version": 1, "credential_preparation_id": "00000000-0000-4000-8000-000000000002", "display_name": "Case application test", "permission_ids": [ "case.read" ], "reason": "Review an owned case application registration", "registration": { "enabled": true, "management_access": false, "post_logout_redirect_uris": [ "https://case.example.test/signed-out" ], "redirect_uris": [ "https://case.example.test/callback" ], "refresh_allowed": false, "resource_audiences": [ "case-api-test" ], "secret_hash_fingerprint": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" }, "target_issuer": "https://owned-issuer.example.test" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/owned-clients', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "catalog_id": "00000000-0000-4000-8000-000000000001", "client_id": "case-app-test", "client_version": 1, "credential_preparation_id": "00000000-0000-4000-8000-000000000002", "display_name": "Case application test", "permission_ids": [ "case.read" ], "reason": "Review an owned case application registration", "registration": { "enabled": true, "management_access": false, "post_logout_redirect_uris": [ "https://case.example.test/signed-out" ], "redirect_uris": [ "https://case.example.test/callback" ], "refresh_allowed": false, "resource_audiences": [ "case-api-test" ], "secret_hash_fingerprint": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" }, "target_issuer": "https://owned-issuer.example.test" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/owned-clients', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"catalog_id":"00000000-0000-4000-8000-000000000001","client_id":"case-app-test","client_version":1,"credential_preparation_id":"00000000-0000-4000-8000-000000000002","display_name":"Case application test","permission_ids":["case.read"],"reason":"Review an owned case application registration","registration":{"enabled":true,"management_access":false,"post_logout_redirect_uris":["https://case.example.test/signed-out"],"redirect_uris":["https://case.example.test/callback"],"refresh_allowed":false,"resource_audiences":["case-api-test"],"secret_hash_fingerprint":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},"target_issuer":"https://owned-issuer.example.test"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/client_propose_v1_projects__project_id__owned_clients_post) ## POST /v1/projects/{project_id}/owned-clients/{policy_id}/approve Independently approve an owned-client proposal Obtains fresh private custody readback before source locks and records an independent current approver with the exact proposal and approved catalog evidence. The approved_pending_readback state still requires separate reviewed installation and product acknowledgement. Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `policy_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; identity__owned_client_router__Reason | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | | string | Yes | | | `project_id` | | string | Yes | | | `target_issuer` | | string | Yes | | | `client_id` | | string | Yes | | | `client_version` | | integer | Yes | | | `generation` | | integer | Yes | | | `display_name` | | string | Yes | | | `catalog_id` | | string | Yes | | | `catalog_digest` | | string | Yes | | | `permission_ids` | | string[] | Yes | | | `registration` | | RegistrationRead | Yes | | | `registration_digest` | | string | Yes | | | `policy_digest` | | string | Yes | | | `credential_preparation_id` | | string \| null | No | | | `custody_binding_digest` | | string \| null | No | | | `status` | | pending_review \| approved_pending_readback \| superseded \| revoked | Yes | | | `proposer` | | string | Yes | | | `approver` | | string \| null | Yes | | | `created_at` | | string | Yes | | | `expires_at` | | string | Yes | | | `actions` | | (approve \| revoke)[] | Yes | | | `revocation` | | RevocationRead \| null | No | | #### 403 Current project authority or independent review required No fields declared in the current specification. #### 409 Current exact proposal, catalog, version or idempotency conflict No fields declared in the current specification. #### 413 Exact JSON request exceeds 64 KiB No fields declared in the current specification. #### 422 Invalid exact reviewed policy or registration No fields declared in the current specification. #### 503 Configured owned issuer authority unavailable No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/owned-clients/REPLACE_WITH_POLICY_ID/approve' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/owned-clients/REPLACE_WITH_POLICY_ID/approve', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/owned-clients/REPLACE_WITH_POLICY_ID/approve', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/client_approve_v1_projects__project_id__owned_clients__policy_id__approve_post) ## POST /v1/projects/{project_id}/owned-clients/{policy_id}/revoke Revoke an owned-client proposal Revoke an owned-client proposal Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `policy_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; identity__owned_client_router__Reason | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | | string | Yes | | | `project_id` | | string | Yes | | | `target_issuer` | | string | Yes | | | `client_id` | | string | Yes | | | `client_version` | | integer | Yes | | | `generation` | | integer | Yes | | | `display_name` | | string | Yes | | | `catalog_id` | | string | Yes | | | `catalog_digest` | | string | Yes | | | `permission_ids` | | string[] | Yes | | | `registration` | | RegistrationRead | Yes | | | `registration_digest` | | string | Yes | | | `policy_digest` | | string | Yes | | | `credential_preparation_id` | | string \| null | No | | | `custody_binding_digest` | | string \| null | No | | | `status` | | pending_review \| approved_pending_readback \| superseded \| revoked | Yes | | | `proposer` | | string | Yes | | | `approver` | | string \| null | Yes | | | `created_at` | | string | Yes | | | `expires_at` | | string | Yes | | | `actions` | | (approve \| revoke)[] | Yes | | | `revocation` | | RevocationRead \| null | No | | #### 403 Current project authority or independent review required No fields declared in the current specification. #### 409 Current exact proposal, catalog, version or idempotency conflict No fields declared in the current specification. #### 413 Exact JSON request exceeds 64 KiB No fields declared in the current specification. #### 422 Invalid exact reviewed policy or registration No fields declared in the current specification. #### 503 Configured owned issuer authority unavailable No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/owned-clients/REPLACE_WITH_POLICY_ID/revoke' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/owned-clients/REPLACE_WITH_POLICY_ID/revoke', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/owned-clients/REPLACE_WITH_POLICY_ID/revoke', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/client_revoke_v1_projects__project_id__owned_clients__policy_id__revoke_post) --- # Owned client custody 1 management API operations. - [POST /v1/projects/{project_id}/owned-clients/credential-intents](/docs/api/operations/intent_v1_projects__project_id__owned_clients_credential_intents_post): Request controlled custody for a proposed owned-client credential ## POST /v1/projects/{project_id}/owned-clients/credential-intents Request controlled custody for a proposed owned-client credential A current approved project owner with exact active sponsorship and recent strong authentication records an audited, short-lived intent for the configured runtime. Idempotency-Key scopes retries to the exact actor and body. This response contains only the intent ID and pending custody status. Controlled private delivery and independent registration review remain required. Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; IntentRequest | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Trimmed printable reason recorded in the accepted Audit Validation: min length 8; max length 500 | | `client_id` | | string | Yes | Exact client ID for the proposed registration Validation: min length 1; max length 128 | | `client_version` | | integer | Yes | Proposed registration version, greater than approved history Validation: minimum 1; maximum 9223372036854775807 | | `destination_runtime` | | string | Yes | Exact locally configured custody runtime Validation: min length 1; max length 128 | ### Responses #### 201 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | | string ยท uuid | Yes | Server-generated canonical intent UUID | | `custody_status` | | pending | Yes | Awaiting controlled private custody delivery | #### 400 Empty or oversized idempotency key No fields declared in the current specification. #### 401 Workforce authentication required No fields declared in the current specification. #### 403 Current owner, sponsorship or recent strong authentication required No fields declared in the current specification. #### 409 Ambiguous sponsorship, client/version binding or concurrent authority conflict No fields declared in the current specification. #### 410 Original replayed intent expired, cancelled or authority revoked No fields declared in the current specification. #### 422 Missing required fields or header, invalid exact payload or audit reason No fields declared in the current specification. #### 503 Disabled custody source or current local key profile unavailable No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/owned-clients/credential-intents' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON", "client_id": "REPLACE_WITH_CLIENT_ID", "client_version": 0, "destination_runtime": "REPLACE_WITH_DESTINATION_RUNTIME" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/owned-clients/credential-intents', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON", "client_id": "REPLACE_WITH_CLIENT_ID", "client_version": 0, "destination_runtime": "REPLACE_WITH_DESTINATION_RUNTIME" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/owned-clients/credential-intents', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON","client_id":"REPLACE_WITH_CLIENT_ID","client_version":0,"destination_runtime":"REPLACE_WITH_DESTINATION_RUNTIME"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/intent_v1_projects__project_id__owned_clients_credential_intents_post) --- # Project authority status 1 management API operations. - [GET /v1/projects/{project_id}/authority-status](/docs/api/operations/project_authority_status): Read scoped project authority status ## GET /v1/projects/{project_id}/authority-status Read scoped project authority status Read current source review and signed activation observations for an approved project as its current owner or a current project approver. A fresh positive Go readback is an observation, not a lasting sign-in guarantee. Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | Validation: min length 1; max length 128 | | `limit` | query | integer | No | Validation: minimum 1; maximum 50 | | `offset` | query | integer | No | Validation: minimum 0; maximum 10000 | ### Request body This operation has no request body. ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | | string | Yes | Validation: min length 1; max length 128 | | `observed_at` | | integer | Yes | Read time, Unix seconds. | | `lifecycle` | | LifecycleStatus | Yes | | | `activation_effectiveness` | | unknown | Yes | Project-wide effectiveness remains unknown; inspect each current signed client observation. | | `clients` | | ClientAuthorityStatus[] | Yes | Validation: max items 50 | | `next_offset` | | integer \| null | Yes | Offset for the next page, or null at the end. | #### 403 Current project owner or approver authority required. No fields declared in the current specification. #### 404 Approved project not found. No fields declared in the current specification. #### 409 More rows exist beyond the bounded pagination ceiling. No fields declared in the current specification. #### 422 Validation Error | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `detail` | | ValidationError[] | No | | ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/authority-status' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/authority-status', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/authority-status', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/project_authority_status) --- # Project lifecycle 6 management API operations. - [GET /v1/projects/{project_id}/lifecycle](/docs/api/operations/read_v1_projects__project_id__lifecycle_get): Read project lifecycle and issuer removal state - [POST /v1/projects/{project_id}/lifecycle/suspend](/docs/api/operations/suspend_route_v1_projects__project_id__lifecycle_suspend_post): Suspend a project - [POST /v1/projects/{project_id}/lifecycle/resume](/docs/api/operations/resume_route_v1_projects__project_id__lifecycle_resume_post): Resume a suspended project - [POST /v1/projects/{project_id}/lifecycle/decommission](/docs/api/operations/decommission_request_v1_projects__project_id__lifecycle_decommission_post): Request irreversible decommission - [POST /v1/projects/{project_id}/lifecycle/decommission/{action_id}/approve](/docs/api/operations/decommission_approve_v1_projects__project_id__lifecycle_decommission__action_id__approve_post): Approve irreversible decommission - [POST /v1/projects/{project_id}/lifecycle/decommission/{action_id}/cancel](/docs/api/operations/decommission_cancel_v1_projects__project_id__lifecycle_decommission__action_id__cancel_post): Cancel a pending decommission request ## GET /v1/projects/{project_id}/lifecycle Read project lifecycle and issuer removal state Scoped to a current owner or project approver. Revocation state is Management ledger state plus authenticated Go receipts. local_sessions is always unobserved. Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | ### Request body This operation has no request body. ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | | string | Yes | | | `name` | | string | Yes | | | `status` | | string | Yes | | | `downstream` | | DownstreamRead | Yes | | | `actions` | | ActionRead[] | Yes | | | `revocations` | | RevocationDetail[] | Yes | | | `allowed` | | (suspend \| resume \| decommission-request \| decommission-approve \| decommission-cancel)[] | Yes | | #### 403 Current scoped authority, independent review or recent strong authentication required No fields declared in the current specification. #### 409 Current project state, target set or idempotency conflict No fields declared in the current specification. #### 422 Invalid exact request No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X GET 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle', { method: 'GET', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}` } }); const result = await response.json(); ``` #### Python ```python import os import requests response = requests.request( 'GET', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN']} ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/read_v1_projects__project_id__lifecycle_get) ## POST /v1/projects/{project_id}/lifecycle/suspend Suspend a project Reversible. Blocks new authority, revokes workforce access through the ordered lifecycle feed and leaves issuer clients installed. Resume does not restore access. Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; identity__owned_client_router__Reason | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | | string | Yes | | | `project_id` | | string | Yes | | | `kind` | | suspend \| resume \| decommission | Yes | | | `status` | | requested \| effective \| cancelled | Yes | | | `requested_by` | | string | Yes | | | `decided_by` | | string \| null | Yes | | | `reason` | | string | Yes | | | `created_at` | | string | Yes | | | `expires_at` | | string \| null | Yes | | | `effective_at` | | string \| null | Yes | | | `completed_at` | | string \| null | Yes | | | `project_status` | | string | Yes | | | `access_revoked` | | integer | Yes | | | `lifecycle_head` | | integer | Yes | | | `revocations` | | RevocationRead[] | Yes | | #### 403 Current scoped authority, independent review or recent strong authentication required No fields declared in the current specification. #### 409 Current project state, target set or idempotency conflict No fields declared in the current specification. #### 422 Invalid exact request No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle/suspend' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle/suspend', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle/suspend', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/suspend_route_v1_projects__project_id__lifecycle_suspend_post) ## POST /v1/projects/{project_id}/lifecycle/resume Resume a suspended project Requires a current project approver other than the suspender. Workforce access must be granted again through the normal reviewed workflow. Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; identity__owned_client_router__Reason | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | | string | Yes | | | `project_id` | | string | Yes | | | `kind` | | suspend \| resume \| decommission | Yes | | | `status` | | requested \| effective \| cancelled | Yes | | | `requested_by` | | string | Yes | | | `decided_by` | | string \| null | Yes | | | `reason` | | string | Yes | | | `created_at` | | string | Yes | | | `expires_at` | | string \| null | Yes | | | `effective_at` | | string \| null | Yes | | | `completed_at` | | string \| null | Yes | | | `project_status` | | string | Yes | | | `access_revoked` | | integer | Yes | | | `lifecycle_head` | | integer | Yes | | | `revocations` | | RevocationRead[] | Yes | | #### 403 Current scoped authority, independent review or recent strong authentication required No fields declared in the current specification. #### 409 Current project state, target set or idempotency conflict No fields declared in the current specification. #### 422 Invalid exact request No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle/resume' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle/resume', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle/resume', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/resume_route_v1_projects__project_id__lifecycle_resume_post) ## POST /v1/projects/{project_id}/lifecycle/decommission Request irreversible decommission Records a request that expires after 72 hours. It changes no project authority until an independent approver approves it. Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; identity__owned_client_router__Reason | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 201 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | | string | Yes | | | `project_id` | | string | Yes | | | `kind` | | suspend \| resume \| decommission | Yes | | | `status` | | requested \| effective \| cancelled | Yes | | | `requested_by` | | string | Yes | | | `decided_by` | | string \| null | Yes | | | `reason` | | string | Yes | | | `created_at` | | string | Yes | | | `expires_at` | | string \| null | Yes | | | `effective_at` | | string \| null | Yes | | | `completed_at` | | string \| null | Yes | | | `project_status` | | string | Yes | | | `access_revoked` | | integer | Yes | | | `lifecycle_head` | | integer | Yes | | | `revocations` | | RevocationRead[] | Yes | | #### 403 Current scoped authority, independent review or recent strong authentication required No fields declared in the current specification. #### 409 Current project state, target set or idempotency conflict No fields declared in the current specification. #### 422 Invalid exact request No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle/decommission' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle/decommission', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle/decommission', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/decommission_request_v1_projects__project_id__lifecycle_decommission_post) ## POST /v1/projects/{project_id}/lifecycle/decommission/{action_id}/approve Approve irreversible decommission Requires an independent current project approver. Queues exact issuer revoke commands. The project becomes decommissioned only after every removal is acknowledged or was never installed. Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `action_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; identity__owned_client_router__Reason | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | | string | Yes | | | `project_id` | | string | Yes | | | `kind` | | suspend \| resume \| decommission | Yes | | | `status` | | requested \| effective \| cancelled | Yes | | | `requested_by` | | string | Yes | | | `decided_by` | | string \| null | Yes | | | `reason` | | string | Yes | | | `created_at` | | string | Yes | | | `expires_at` | | string \| null | Yes | | | `effective_at` | | string \| null | Yes | | | `completed_at` | | string \| null | Yes | | | `project_status` | | string | Yes | | | `access_revoked` | | integer | Yes | | | `lifecycle_head` | | integer | Yes | | | `revocations` | | RevocationRead[] | Yes | | #### 403 Current scoped authority, independent review or recent strong authentication required No fields declared in the current specification. #### 409 Current project state, target set or idempotency conflict No fields declared in the current specification. #### 422 Invalid exact request No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle/decommission/REPLACE_WITH_ACTION_ID/approve' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle/decommission/REPLACE_WITH_ACTION_ID/approve', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle/decommission/REPLACE_WITH_ACTION_ID/approve', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/decommission_approve_v1_projects__project_id__lifecycle_decommission__action_id__approve_post) ## POST /v1/projects/{project_id}/lifecycle/decommission/{action_id}/cancel Cancel a pending decommission request Cancel a pending decommission request Authentication: bearer access token with audience `taifa-management`. Endpoint roles and eligibility are reviewed separately from the OpenAPI bearer scheme. No operation-specific scopes are declared in the OpenAPI document. Bearer authentication and endpoint authorization requirements still apply. ### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `project_id` | path | string | Yes | | | `action_id` | path | string | Yes | | | `idempotency-key` | header | string | Yes | | ### Request body #### application/json Required; identity__owned_client_router__Reason | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `reason` | | string | Yes | Validation: min length 8; max length 500 | ### Responses #### 200 Successful Response | Field | Variant | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | | string | Yes | | | `project_id` | | string | Yes | | | `kind` | | suspend \| resume \| decommission | Yes | | | `status` | | requested \| effective \| cancelled | Yes | | | `requested_by` | | string | Yes | | | `decided_by` | | string \| null | Yes | | | `reason` | | string | Yes | | | `created_at` | | string | Yes | | | `expires_at` | | string \| null | Yes | | | `effective_at` | | string \| null | Yes | | | `completed_at` | | string \| null | Yes | | | `project_status` | | string | Yes | | | `access_revoked` | | integer | Yes | | | `lifecycle_head` | | integer | Yes | | | `revocations` | | RevocationRead[] | Yes | | #### 403 Current scoped authority, independent review or recent strong authentication required No fields declared in the current specification. #### 409 Current project state, target set or idempotency conflict No fields declared in the current specification. #### 422 Invalid exact request No fields declared in the current specification. ### Request examples Illustrative only. Replace placeholders and keep management tokens on the server. #### cURL ```sh curl -X POST 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle/decommission/REPLACE_WITH_ACTION_ID/cancel' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'idempotency-key: REPLACE_WITH_IDEMPOTENCY_KEY' \ -H 'Content-Type: application/json' \ --data '{ "reason": "REPLACE_WITH_REASON" }' ``` #### TypeScript (Node.js/server-side) ```typescript const response = await fetch('https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle/decommission/REPLACE_WITH_ACTION_ID/cancel', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TAIFA_MANAGEMENT_TOKEN}`, 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "reason": "REPLACE_WITH_REASON" }) }); const result = await response.json(); ``` #### Python ```python import os import json import requests response = requests.request( 'POST', 'https://YOUR_IDENTITY_HOST/v1/projects/REPLACE_WITH_PROJECT_ID/lifecycle/decommission/REPLACE_WITH_ACTION_ID/cancel', headers={'Authorization': 'Bearer ' + os.environ['TAIFA_MANAGEMENT_TOKEN'], 'idempotency-key': 'REPLACE_WITH_IDEMPOTENCY_KEY'}, json=json.loads('{"reason":"REPLACE_WITH_REASON"}') ) response.raise_for_status() ``` ### Response example No response example in the current specification. [Request and response examples](/docs/api/operations/decommission_cancel_v1_projects__project_id__lifecycle_decommission__action_id__cancel_post)