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

# Partners in TED

> Confine a partner's TED credential to the Midaz organizations it acts for, name the organization on every request, and read the refusals it receives.

A [partner](https://docs.lerian.studio/en/platform/access-manager/features/partners/overview) can call the TED plugin with its own credential. You confine that credential to the Midaz organizations it acts for. You need this when one TED deployment serves several organizations.

Every TED partner needs a scope.

## Step by step

***

**1. Choose the organizations the partner acts for**

TED has one restriction:

| Restriction | API field | What the partner reaches | What it is refused |
| - | - | - | - |
| **Midaz organization** | `organizationId` | The transfers of each organization you list: initiate, sign, process, and return a transfer, read a transfer, list transfers, read the pending reconciliation list, and read the dashboard. | Every other organization, and the routes that act on the whole tenant (see [Routes that no partner reaches](#routes-that-no-partner-reaches)). |

The ledger and the accounts of a transfer are not a TED restriction. TED finds the ledger from the sender's account. To confine a partner to some ledgers or accounts, also give it a [Midaz scope](https://docs.lerian.studio/en/platform/access-manager/features/partners/midaz.md). Midaz then applies that scope to the postings TED makes for the partner. See [The partner's Midaz rules apply to its transfers](#the-partners-midaz-rules-apply-to-its-transfers).

**2. Give the partner its permissions and scope**

Create the partner, or change it, in the [Console](https://docs.lerian.studio/en/platform/access-manager/features/partners/console.md) or with the [Identity API](https://docs.lerian.studio/en/platform/access-manager/features/partners/api.md). The product slug is `plugin-br-bank-transfer`. The restriction accepts several organizations.

* Add the scope entry for the organizations. Without it, Access Manager refuses the partner with `400` and `IDE-1060`.
* Check the resources and actions. The most you can give is what the `plugin-br-bank-transfer-editor-role` role holds in your tenant. Above that, Access Manager refuses with `IDE-1043`.

You can give a partner these actions on the resource `transfers`: `create`, `process`, `read`, `list`, and `return`. Every other action acts on the whole tenant: the cancellation and the reconciliation retry of a transfer, the TED IN poller and its replay, the reconciliation cycle, the manual resolution and the scope repair, the webhooks, the runtime settings, and the event catalog. Access Manager refuses them with `400` and `IDE-1056`, and the Console marks the line **Outside the scope**.

**3. Create its TED application**

Create the partner's application with the product `plugin-br-bank-transfer`. See [Create the partner's applications](https://docs.lerian.studio/en/platform/access-manager/features/partners/api.md#create-the-partners-applications) in the API guide, or [in the Console](https://docs.lerian.studio/en/platform/access-manager/features/partners/console.md#create-the-partners-applications). Send the client ID and the client secret to the partner through a secure channel.

**4. Name the organization on every request**

Every request names the organization in the `X-Organization-Id` header, which TED already requires on these routes. The value must be inside the partner's scope. A request without it is refused.

| Routes | Writes | Reads and routes by ID |
| - | - | - |
| Transfers: `/v1/transfers/initiate`, `/v1/transfers/signing/prepare`, `/v1/transfers/process` | Header `X-Organization-Id` | — |
| One transfer: `/v1/transfers/{transferId}`, `/v1/transfers/{transferId}/return` | Header `X-Organization-Id` | Header `X-Organization-Id` |
| Lists: `/v1/transfers`, `/v1/transfers/reconciliation/pending`, `/v1/transfers/dashboard/summary` | — | Header `X-Organization-Id` |

The header takes one organization. A transfer of another organization answers `404`, even when that organization is in the partner's scope: name the organization the transfer belongs to.

**5. Confirm that it works**

Use the partner's credential. List the transfers of an organization in the partner's scope. The answer is `200`:

```bash theme={null}
TED_BASE_URL="https://ted.<your-domain>"                 # your TED base URL
TED_BEARER_TOKEN="paste-the-partner-access-token-here"
OWN_ORGANIZATION_ID="paste-an-organization-in-the-scope"

curl -s -o /dev/null -w '%{http_code}\n' \
  -H "Authorization: Bearer ${TED_BEARER_TOKEN}" \
  -H "X-Organization-Id: ${OWN_ORGANIZATION_ID}" \
  "${TED_BASE_URL}/v1/transfers"
```

Send the same request with an organization outside the partner's scope. The answer is `403` with `BTF-0405`.

## The partner's Midaz rules apply to its transfers

***

TED posts each transfer to Midaz while it serves the partner's request. When the partner also has Midaz permissions, Midaz applies the partner's Midaz scope to that posting. For example, a partner restricted in Midaz to one ledger cannot move money from another ledger of the same organization through TED.

* When Midaz refuses the partner, TED answers `403` with `BTF-0405`, and `upstream.code` carries the Midaz code, for example `AUT-1019`. The refusal moves no money, and a repeat gets the same refusal until you change the partner's Midaz permissions or scope.
* The Midaz scope does not narrow what the partner reads in TED. Reading a transfer, listing transfers, the pending reconciliation list, and the dashboard show every TED transfer of the organization, also the transfers of ledgers outside the partner's Midaz scope. TED answers these reads from its own records and does not call Midaz. Give a partner `read` and `list` only when it can see all the transfers of the organization.
* A partner with no Midaz permissions is decided by its TED permissions and scope only.
* You can give the partner its Midaz rules in the same Console flow, or later on the Midaz product.
* A TED IN credit, the reconciliation, and the other background work run without a partner. The partner's rules do not apply there.

## Routes that no partner reaches

***

A partner with a TED scope is refused with `403` and `BTF-0405` on the routes that name no organization:

* The TED IN reads: `GET /v1/transfers/ted-in/poller`, `GET /v1/transfers/ted-in/retained`, `GET /v1/transfers/ted-in/undeliverables`, and `GET /v1/transfers/ted-in/reconciliation-gaps`.
* The routing report: `GET /v1/transfers/routing/preflight`.

These routes show data of every organization of your tenant. Use an application of your own institution for them.

## If something fails

***

| Code | Status | What it means | What to do |
| - | - | - | - |
| `BTF-0405` | 403 | The request names an organization outside the partner's scope, names none, or is outside the partner's permissions or IP allowlist. With `upstream.code`, Midaz refused the partner: the transfer is outside the partner's Midaz permissions or scope. | Send `X-Organization-Id` with an organization in the partner's scope. Check also the partner's permissions and IP allowlist. With `upstream.code`, check the partner's Midaz permissions and scope. |
| `BTF-0401` | 401 | The partner is suspended, or the request is outside its validity window. | Reactivate the partner, or change its validity window. |
| `BTF-0200` | 404 | The transfer does not belong to the organization the request names. Nothing is read or changed. | Check the transfer ID and the organization. |
| `BTF-0404` | 404 | Your institution does not operate the organization on TED. | Check the organization. |
| `BTF-2000` | 503 | Midaz did not answer. | Read the transfer, then send the request again as the endpoint describes, with a new `X-Idempotency` key. |

`BTF-0405` does not say whether the permissions or the scope refused the request. This is on purpose: a partner cannot use a refusal to learn which organizations exist outside its scope.

For the refusals when you create or change a partner, see [Error codes](https://docs.lerian.studio/en/platform/access-manager/features/partners/api.md#error-codes) in the API guide.


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