> ## 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 Midaz

> Confine a partner's Midaz credential to one organization and, inside it, to the ledgers, accounts, aliases, portfolios, segments, holders, or routes you choose, and read the refusals it receives.

A [partner](https://docs.lerian.studio/en/platform/access-manager/features/partners/overview) can call Midaz with its own credential. In Midaz, you confine that credential to one organization and, if you want, to some items inside it. This page shows how to choose that scope, what each choice reaches, and what the partner receives when it goes outside it.

Every Midaz partner needs a scope. The organization is always required.

## Step by step

***

**1. Choose where the partner acts**

Pick the narrowest scope that covers what the partner needs. Each row is a restriction you can add. The **API field** is the `field` of a scope entry; the Console shows the name in the first column.

| Restriction | API field | What the partner reaches | What it is refused |
| - | - | - | - |
| **Midaz organization** (required, one value) | `organizationId` | With no other restriction: everything its permissions give inside that organization, in any ledger. | Every other organization. |
| **Ledger** | `ledgerId` | Its own ledgers by ID, and the accounts, balances, and transactions inside them. It also reads its organization. | Other ledgers, the list of the organization's ledgers, holders, instruments without a ledger, the CRM audit records, and operation and transaction routes (see the last row). |
| **Account** | `accountId` | Each listed account, its balances, and its operations, by account ID. | Listing the accounts of the ledger, a balance by its own ID, transactions (list and by ID), and the routes addressed by alias. |
| **Account alias** | `accountAlias` | The same as **Account**, through the routes addressed by alias. It can create transactions from its own aliases. | The routes addressed by account ID. |
| **Portfolio** or **Segment** | `portfolioId`, `segmentId` | Listing accounts filtered by its own portfolio or segment, and creating accounts in it. | An account by ID, balances, and transactions. |
| **Holder** | `holderId` | Its own holders, their accounts, and the account list filtered by its own holder. | Listing all holders. |
| **Operation route** or **Transaction route** | `operationRouteId`, `transactionRouteId` | Only the routes whose IDs you list, read by ID under the partner's ledger. | Listing routes, and reading a route under the organization instead of the ledger. |

The scope catalog lists every Midaz restriction, including the ones not in this table. Read it with [Retrieve a product's scope catalog](https://docs.lerian.studio/en/reference/platform/access-manager/retrieve-a-product-s-scope-catalog.md) for `midaz`.

Some rules apply to every scope:

* A request that does not name an item of a restricted type is refused when it acts on what that restriction confines. For example, a partner restricted to some ledgers cannot list all the ledgers of its organization. A request outside what the restriction confines only needs the organization.
* A request that lists several values, such as several aliases in a body or a query, is refused when any one of them is outside the scope.
* Routes that act on the whole tenant, such as listing organizations or reading tenant settings, are refused to every partner.

**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 `midaz`.

* Add the scope entry for the organization, with exactly one value. Without it, Access Manager refuses the partner with `400` and `IDE-0001`. With two organizations, it refuses with `IDE-0002`.
* Add the other restrictions you chose in step 1.
* Check the resources and actions. The most you can give is what the `midaz-editor-role` role holds in your tenant. Above that, Access Manager refuses with `IDE-1043`.

Access Manager checks each write you give against the scope:

* A write that acts on the whole tenant, such as creating an organization, is never given to a partner.
* A write that acts above the partner's scope is refused. For example, a partner restricted to one ledger cannot receive the right to create, change, or delete ledgers, holders, or operation and transaction routes: those writes act on the whole organization.
* Both refusals answer `400` with `IDE-1056`. The Console marks the line **Outside the scope**.

To give read access to operation or transaction routes, list the route IDs in the scope. Without them, Access Manager refuses the partner with `400` and `IDE-1052`. Access Manager does not check that a route ID belongs to the partner's ledger: the partner reads every route whose ID you list. List only the routes of its own ledgers.

Do not give `transactions` with `post` to a partner restricted only by portfolio, segment, or holder. Access Manager accepts it, but every transaction of that partner is refused.

**3. Create its Midaz application**

Create the partner's application with the product `midaz`. 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. Tell the partner how to name its items**

The partner names its items in the paths, queries, and bodies that Midaz already has. Nothing extra is sent. These cases need attention:

* **Accounts filtered by portfolio, segment, or holder.** Send `portfolio_id`, `segment_id`, or `holder_id` in the query of the account list.
* **Accounts of a holder.** Send `ledger_id` in the query, with a ledger inside the scope. The answer holds only that ledger's accounts.
* **New accounts.** A partner restricted by portfolio or segment sends its own `portfolioId` or `segmentId` in the body. A partner restricted by account sends one of its own accounts in `parentAccountId`.
* **Transactions on the `/v2/transactions` routes** (`direct`, `hold`, `block`, `unblock`, and `batch`). Every debit and every credit names an organization and a ledger inside the scope. A partner restricted by alias can use only its own aliases on both sides, so it moves money only between its own accounts.
* **Transactions on the `/v1` ledger routes** (`json`, `outflow`, `annotation`, `block`, and `unblock`). The source aliases in `send.source.from[].accountAlias` must be the partner's own.

> [!WARNING]
>
> On the `/v1` transaction routes, only the source accounts are checked. A partner restricted by alias can send money from its own aliases to any account of its ledger. To keep it between its own accounts, give it only the `/v2/transactions` routes, or do not give it `transactions` with `post`.

A partner restricted by account or alias cannot use these transaction routes: `inflow` on `/v1`, and commit, cancel, revert, change, read by ID, or list. It can create a hold, but it cannot commit or cancel it. A partner restricted by account ID cannot create transactions on the `/v1` routes. To let it move money from specific accounts, restrict it by alias.

**5. Confirm that it works**

This check assumes the partner has the `accounts` resource with the `get` action on Midaz, and a scope restricted to one organization and one or more of its ledgers. Use the partner's credential. List the accounts of a ledger inside its scope. The answer is `200`:

```bash theme={null}
MIDAZ_BASE_URL="https://midaz.<your-domain>"              # your Midaz ledger API base URL
MIDAZ_BEARER_TOKEN="paste-the-partner-access-token-here"
ORGANIZATION_ID="paste-the-organization-id-here"          # the organization in the partner's scope
LEDGER_ID="paste-a-ledger-id-in-the-scope-here"

curl -s -o /dev/null -w '%{http_code}\n' \
  -H "Authorization: Bearer ${MIDAZ_BEARER_TOKEN}" \
  "${MIDAZ_BASE_URL}/v1/organizations/${ORGANIZATION_ID}/ledgers/${LEDGER_ID}/accounts"
```

Send the same request with a ledger of the same organization that is outside the scope. The answer is `403` with code `AUT-1020`.

## If something fails

***

| Code | Status | What it means | What to do |
| - | - | - | - |
| `AUT-1020` | 403 | The request is outside the partner's permissions or outside its scope, or it does not name an item the scope requires. The message names the resource and the action: "the credential is not allowed to perform `<resource>:<action>` on this request". | Check that the request names its organization and its items, and that they are in the partner's scope. Check also that the partner has the permission for that route. |
| `0047` | 400 | The request names the same item twice with different values, for example one ledger in the path and another in the body. | Send the same value in every place. |
| `AUT-1009` | 401 | The partner is suspended. | Reactivate the partner. |
| `AUT-1010` | 401 | The request is outside the partner's validity window. | Change the validity window. |
| `AUT-0021` | 403 | The request comes from an address outside the partner's IP list. | Add the address to the partner's IP list. |

The answer 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 items exist outside its scope.

For every other code, see the [Midaz error list](https://docs.lerian.studio/en/reference/products/midaz/error-list.md). 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.