> For the complete documentation index, see [llms.txt](https://tri.gitbook.io/tri-doc/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://tri.gitbook.io/tri-doc/liquidity-pool/add-mastercard-card/start-mastercard-enrolment.md).

# Start MasterCard Enrolment

### Liquidity Pool

<mark style="color:green;">`POST`</mark> <https://sandbox.triangle.digital/api/v2/liquidity\\_pool/clients/{client\\_id}/mastercard/session>

**Step 1 of 2** of [Add MasterCard Card](/tri-doc/liquidity-pool/add-mastercard-card.md). Nothing is stored by this call — the card appears on the holder only after step 2.

Starts a MasterCard enrolment for one holder — an employee or an individual consumption — and answers with everything a browser needs to open MasterCard's Consent UI. The card is entered on MasterCard's own page: no call of this API ever takes card details.

How the flow goes:

1. Call this endpoint and open `iframe_url` in an iframe. Callers that prefer MasterCard's own wrapper load `js_url` and pass it the `jwt` instead.
2. Check every `postMessage` the widget sends against `origin` — messages from any other origin must be ignored.
3. When the widget reports `Close` with `status: 'success'`, its message carries the card reference and the consent id. Send them to [Save MasterCard Card](/tri-doc/liquidity-pool/add-mastercard-card/save-mastercard-card.md) — only then is the card stored.

The material is valid for 15 minutes (`expires_at`). After that, start again — a stale `iframe_url` cannot be reused.

A holder that already has a MasterCard card is refused: remove the existing card first. A Stripe card on the same holder is independent and does not get in the way.

**Path parameters**

<table data-full-width="true" data-search="false"><thead><tr><th width="230">Name</th><th width="110">Type</th><th>Description</th><th width="210">Where to take it from</th></tr></thead><tbody><tr><td><code>client_id</code></td><td>integer</td><td><strong>Required.</strong> The client the holder belongs to.</td><td><a href="/tri-doc/liquidity-pool/get-clients.md">Get Clients</a> — <code>client_id</code></td></tr></tbody></table>

**Headers**

<table data-full-width="true"><thead><tr><th>Name</th><th>Value</th></tr></thead><tbody><tr><td>Content-Type</td><td><code>application/json</code></td></tr></tbody></table>

**Body**

<table data-full-width="true" data-search="false"><thead><tr><th width="250">Name</th><th width="110">Type</th><th>Description</th><th width="260">Example</th></tr></thead><tbody><tr><td><code>hash</code></td><td>string</td><td><strong>Required.</strong> API key.</td><td>fk5f0iuy-rr06-j4x3-i75b-fy2s67s4ilo1</td></tr><tr><td><code>employee_id</code></td><td>integer</td><td>The employee the card is enrolled for. Exactly one of <code>employee_id</code> and <code>individual_consumption_id</code> is required. From <a href="/tri-doc/liquidity-pool/get-employees.md">Get Employees</a> — <code>employee_id</code>.</td><td>345</td></tr><tr><td><code>individual_consumption_id</code></td><td>uuid</td><td>The individual consumption the card is enrolled for; Business clients only. Exactly one of <code>employee_id</code> and <code>individual_consumption_id</code> is required. From <a href="/tri-doc/liquidity-pool/get-individual-consumptions.md">Get Individual Consumptions</a> — <code>individual_consumption_id</code>.</td><td>68117898-4278-499f-b96b-78173f3d2040</td></tr></tbody></table>

```json
{
    "hash": "fk5f0iuy-rr06-j4x3-i75b-fy2s67s4ilo1",
    "employee_id": 345
}
```

**Response fields**

<table data-full-width="true" data-search="false"><thead><tr><th width="300">Field</th><th width="110">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>message</code></td><td>string</td><td>Human-readable result of the call.</td></tr><tr><td><code>success</code></td><td>boolean</td><td>Whether the enrolment was started; a refused call answers HTTP 400.</td></tr><tr><td><code>data.iframe_url</code></td><td>string</td><td>The URL to open in an iframe — MasterCard's Consent UI with the signed token already in it.</td></tr><tr><td><code>data.origin</code></td><td>string</td><td>Origin every <code>postMessage</code> from the widget must be checked against.</td></tr><tr><td><code>data.expires_at</code></td><td>string</td><td>When the material stops working, MM/DD/YYYY HH:MM:SS UTC +00:00. 15 minutes after the call.</td></tr><tr><td><code>data.jwt</code></td><td>string</td><td>The signed token, for callers that load MasterCard's own wrapper instead of using <code>iframe_url</code>.</td></tr><tr><td><code>data.js_url</code></td><td>string</td><td>MasterCard's Consent UI script, for the same case.</td></tr><tr><td><code>operations_count</code></td><td>integer</td><td>Always <code>1</code>.</td></tr></tbody></table>

**Response**

{% tabs %}
{% tab title="200" %}
{% code fullWidth="false" %}

```json
{
    "message": "MasterCard enrolment started successfully.",
    "success": true,
    "data": {
        "iframe_url": "https://sandbox.consents.mastercard.com/?t=eyJhbGciOiJSUzI1NiIsImtpZCI6...",
        "origin": "https://sandbox.consents.mastercard.com",
        "expires_at": "08/14/2026 10:22:50 UTC +00:00",
        "jwt": "eyJhbGciOiJSUzI1NiIsImtpZCI6...",
        "js_url": "https://sandbox.consents.mastercard.com/ConsentUI.js"
    },
    "operations_count": 1
}
```

{% endcode %}
{% endtab %}

{% tab title="400" %}
Nothing was started. The `message` says what exactly: `MasterCard card already set.`; `Provide either employee_id or individual_consumption_id.` or `Provide either employee_id or individual_consumption_id, not both.`; `'employee_id' must be a positive integer.`; `Employee not found for this client.` or `Individual consumption not found for this client.`; `This client is not a Business account.` — an individual consumption was named for a non-Business client; `Unable to start the MasterCard flow.`

```json
{
    "message": "MasterCard card already set.",
    "success": false,
    "data": [],
    "operations_count": 1
}
```

{% endtab %}
{% endtabs %}
