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

# Consent

> How texting consent works on MRC, and the request → poll → resend flow your app runs when a send is blocked.

Advisory firms using MRC typically require **express consent** (A2P/10DLC
compliance) before an advisor can text a contact. MRC enforces this
server-side on every send — your app never has to decide *whether* consent is
required, only react when a send reports it.

## The consent model

Every contact's messaging number has one consent state on the advisor's
account:

| `state`    | Meaning                                                    |
| ---------- | ---------------------------------------------------------- |
| `none`     | Never asked, or consent record cleared                     |
| `pending`  | A consent request was sent; the contact hasn't replied yet |
| `accepted` | The contact opted in — sends go through                    |

Two account-level settings (managed by the firm, not your app) shape the
behavior you'll observe:

* **Consent enabled** — if the firm doesn't require consent, sends never
  block and states are irrelevant to you.
* **Response required** — some firms accept "notified" as consent: the
  consent request itself flips the contact to `accepted` without waiting for
  a reply. Others require the contact to reply (e.g. "ACCEPT") before the
  state changes.

<Note>
  Don't branch on these settings — you can't read them, and you don't need
  to. The send response tells you everything: blocked sends land in
  `failures[]`, allowed sends in `successes[]`.
</Note>

## The conditional consent path

```mermaid theme={null}
flowchart TD
    A["POST /messages { phone, text }"] --> B{recipient in<br/>failures[] with<br/>'has not consented'?}
    B -->|no| Z[Done — message sent ✓]
    B -->|yes| C["POST /consent-requests<br/>{ phoneNumbers: [phone] }"]
    C --> D["Contact receives the firm's consent SMS<br/>('Reply ACCEPT to opt in …')"]
    D --> E["GET /consents?phone=…<br/>poll: 30s × 5 min, then 5 min, stop at 24h"]
    E --> F{state}
    F -->|pending| E
    F -->|accepted| G["Resend the original message ✓"]
    F -->|"still pending at 24h"| H["Stop polling.<br/>Surface to your user; a new consent<br/>request can be sent later"]
```

### 1. Request consent

```bash theme={null}
curl -X POST "$MRC_API_BASE/v1/mrc/messaging/consent-requests" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "x-api-key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "phoneNumbers": ["+12185551234"] }'
```

```json theme={null}
{
  "successes": [{ "memberId": 24, "consentState": "pending" }],
  "failures": []
}
```

The contact receives the firm's configured consent message from the advisor's
number. `consentState` in the response tells you where things landed
immediately — on "response required" firms it will be `pending`; on
notify-only firms it can already be `accepted`, in which case skip polling
and resend now.

Behavior notes:

* **No cooldown** — this is the same operation as the advisor's in-app
  "request consent" button, and like the button it will happily send again if
  you call it again. Throttle re-requests on your side.
* **Already accepted → `400`** — requesting consent for a number that has
  already opted in is rejected; check status first if you're unsure.
* **Account not configured for consent → `409 conflict`** — the firm's group
  hasn't set up consent collection; this needs FMG configuration, not a
  retry.
* Batch is supported: pass several `phoneNumbers` and read per-number
  `successes[]`/`failures[]`.

### 2. Poll consent status

```bash theme={null}
curl "$MRC_API_BASE/v1/mrc/messaging/consents?phone=%2B12185551234" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "x-api-key: $API_KEY"
```

```json theme={null}
{ "memberId": 24, "state": "pending", "lastChanged": 1789585293164 }
```

Recommended cadence: **every 30 seconds for the first 5 minutes** (most
contacts who opt in do so immediately), **then every 5 minutes, stopping at
24 hours**. `lastChanged` is epoch milliseconds of the last state change —
useful for showing "requested 2 hours ago" in your UI. Lookup by `memberId`
query parameter is also supported if you stored one.

### 3. Resend

When `state` is `accepted`, resend the original message — the same `POST
/messages` call from step 0. Nothing about the send changes.

## Opt-outs

Contacts can reply **STOP** at any time; MRC handles the reply, confirms the
unsubscribe to the contact, and blocks subsequent sends to them (those sends
land in `failures[]`). **START** re-subscribes. Your app doesn't manage any
of this — just keep reading the per-recipient outcomes.

## What you never need

No contact CRUD, no member management, no consent-record administration —
the firm's advisors and FMG manage those in MyRepChat itself. Your entire
consent surface is the three calls above, keyed by phone number.
