> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tied.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Contact consent report

> Read the current consent report for one account-owned contact.

`GET /api/v1/accounts/{account_id}/contacts/{contact_id}/consent` returns the existing `Consent::Report` for one contact. It requires an authenticated account administrator. The account is taken from the authenticated request and the contact is looked up within that account. There is no Studio feature gate. The account API accepts its supported signed-in user and account API token authentication methods; send one authentication method per request.

The inherited account login-block decision controls ordinary account reads. An open suspension with login blocking enabled can return `401` even when the account status is active. An open suspension can also explicitly permit ordinary reads while the account status remains suspended. When no open suspension controls the decision, the account status supplies the fallback, so a suspended account returns `401`. An authorized own-account read-only staff impersonation can still read this report for a suspended account. Normal account membership, administrator authorization, and contact scoping still apply. A trial-locked account can also read this report.

The request has no query parameters. Extra request values do not filter or change the report. A successful read does not write the contact or consent ledger. It emits one structured log entry containing user, account and contact IDs plus `generated_at`; there is no durable audit row for this read.

## Reading the report

The response includes `contact_id`, `generated_at`, `history_limit` (currently 100), `merged_contact_ids`, `legacy_opt_outs`, and `inboxes`. An empty `inboxes` array means no ledger events were found. It is not proof of consent or that all sends are allowed. `legacy_opt_outs` separately lists AMB and RCS inbox IDs that their existing legacy readers report as opted out; it has no SMS key.

Each returned inbox has its channel and both purpose entries. `state_now` is the existing ledger policy answer at `generated_at`, with an `allowed` boolean and a reason string. The reason vocabulary can expand. A transactional `allowed: true` means opt-in is not required for that transactional purpose; it is not recorded consent. Current deployment enforcement varies by channel and send path, so this report does not guarantee that a send is allowed or blocked.

Each purpose has at most 100 newest history events and a `truncated` flag. Events dated in the future can appear in history but do not decide the current state. A voided event remains visible with `voided: true`, while active events omit that key. `evidence_event_id` and `evidence_event` identify the policy's deciding event separately from the bounded history, so the deciding event may be older than the returned 100 rows. Merged ledger events retain their original `captured_contact_id`; the report lists those prior IDs in `merged_contact_ids`.

Event entries include ledger IDs, state, purpose, mechanism, actor and source references, effective and recorded times, and allowlisted evidence identifiers. Only string values of `disclosure_version`, `disclosure_sha256`, and `form_ref` are returned from evidence. Stored message text and other evidence keys are omitted. `source_ref`, `form_ref`, and metadata originate in source data and should be treated as untrusted values.

## Current surface and requested gaps

This endpoint supplies only a partial read for the requested consent and outreach surface. The following actions are proposals only; there are no callable routes or operation IDs for them. Their implementation and exposure decisions belong to ENG-5898. “Read” is a proposed risk class, not approval to expose an operation.

| Requested action | Current availability |
| - | - |
| `list` | Missing; gap ENG-5898. |
| `summary` | Missing; gap ENG-5898. |
| `held` | Missing; gap ENG-5898. |
| `channelEvidence` | Missing; gap ENG-5898. |
| `recordOptions` | Missing; gap ENG-5898. |
| `consentPeople` | Partially reusable from this per-contact report only; full collection surface missing under ENG-5898. |
| `consentSettings` | Missing; gap ENG-5898. |
| `captureMethods` | Missing; gap ENG-5898. |
| `consentEvidence` | Partially reusable from this per-contact report only; full evidence surface missing under ENG-5898. |
| `exportStatus` | Missing; gap ENG-5898. |
| `exportRows` | Missing; gap ENG-5898. |
| `importRejected` | Missing; gap ENG-5898. |
| `resolveHeld` | Missing; proposed action can cause outbound effects; not implemented or tested. |
| `setEnforcement` | Missing; proposed compliance-sensitive write; not implemented or tested. |
| `setCaptureMethod` | Missing; proposed compliance-sensitive write; not implemented or tested. |
| `recordConsent` | Missing; proposed consent-record write; not implemented or tested. |
| `recordWithdrawal` | Missing; proposed consent-record write; not implemented or tested. |
| `importPreview` | Missing; proposed read only; no route exists. |
| `importConsent` | Missing; proposed consent import write; not implemented or tested. |
| `startExport` | Missing; proposed personal-data export; not implemented or tested. |
| `cancelExport` | Missing; proposed personal-data export control; not implemented or tested. |

No proposal here is approved for activation. All future writes remain risky pending approval. Proposed future behavior includes append-only consent history that must not be deleted, immediate no-send behavior after a recorded withdrawal, repeat-safe withdrawals, and enforcement before sends; failed imports must not write rejected rows. `importPreview` is proposed as a dry run with no contact, ledger or outbound effects. Proposed event payloads contain IDs and counts only, never contact content. These requirements remain unimplemented and unverified. Proposed event names are `consent.recorded`, `consent.withdrawn`, `consent.imported`, `consent.capture_method_changed`, `outreach.enforcement_changed`, `outreach.held_resolved`, and `outreach.export_ready`; delivery is not claimed. Proposal metadata remains unapproved, MCP-hidden and SDK-excluded pending the ENG-5898 decisions.

## Responses

* `200`: report for the account-owned contact.
* `400`: conflicting credential methods were supplied.
* `401`: missing or invalid authentication, non-member account access, or an ended impersonation session.
* `403`: non-administrator role or a structured impersonation refusal.
* `404`: contact does not exist in the authenticated account.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.