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

# Gerenciar parceiros pela API

> Crie, leia, altere e exclua parceiros com a Identity API, leia os catálogos de escopo dos produtos, crie aplicações de parceiro e trate os códigos de erro.

A Identity API gerencia [parceiros](https://docs.lerian.studio/pt/platform/access-manager/features/partners/overview) e as aplicações deles. Use-a quando você gerencia parceiros pelas suas próprias ferramentas em vez do Console.

## Antes de começar

***

Para gerenciar parceiros, um usuário precisa das permissões `partners` de `plugin-identity`: `get` para ler parceiros e catálogos de escopo, `post` para criar um parceiro, `patch` para alterar um e `delete` para excluir um. Gerenciar as aplicações dele precisa das permissões `applications` `get`, `post` e `delete`. O papel `plugin-identity-editor-role` tem todas elas.

## As operações

***

| Operação | O que faz | Referência |
| - | - | - |
| `GET /v1/partners` | Lista os seus parceiros, uma página por vez, com `applicationsCount` para cada um. | [Listar parceiros](https://docs.lerian.studio/pt/reference/platform/access-manager/list-partners.md) |
| `POST /v1/partners` | Cria um parceiro. Retorna `201` com o novo parceiro e o `id` dele. Não cria nenhuma aplicação. | [Criar um parceiro](https://docs.lerian.studio/pt/reference/platform/access-manager/create-a-partner.md) |
| `GET /v1/partners/{id}` | Retorna um parceiro. | [Consultar um parceiro](https://docs.lerian.studio/pt/reference/platform/access-manager/retrieve-a-partner.md) |
| `PATCH /v1/partners/{id}` | Altera um parceiro: o nome, as permissões, o escopo, a janela de validade, a lista de IPs permitidos ou o estado dele. | [Atualizar um parceiro](https://docs.lerian.studio/pt/reference/platform/access-manager/update-a-partner.md) |
| `DELETE /v1/partners/{id}` | Exclui um parceiro sem aplicações. Retorna `204`. | [Excluir um parceiro](https://docs.lerian.studio/pt/reference/platform/access-manager/delete-a-partner.md) |
| `GET /v1/partners/ceiling` | Retorna o máximo que você pode dar a um parceiro no produto que o parâmetro de consulta `product` nomeia. | [Consultar o teto de parceiro de um produto](https://docs.lerian.studio/pt/reference/platform/access-manager/retrieve-the-partner-ceiling-of-a-product.md) |
| `GET /v1/scope-catalog` | Lista os catálogos de escopo que os produtos publicaram, com `partners` para cada um. | [Listar catálogos de escopo](https://docs.lerian.studio/pt/reference/platform/access-manager/list-scope-catalogs.md) |
| `GET /v1/scope-catalog/{product}` | Retorna o catálogo de escopo de um produto. Um produto sem catálogo retorna `404` com `IDE-1053`. | [Consultar o catálogo de escopo de um produto](https://docs.lerian.studio/pt/reference/platform/access-manager/retrieve-a-product-s-scope-catalog.md) |

Para saber quais dimensões um produto aceita em `scope`, leia o catálogo de escopo dele. Cada dimensão tem um `name` e as flags `required`, `multi` e `explicit`.

## Os campos do parceiro

***

| Campo | Obrigatório na criação | Significado |
| - | - | - |
| `displayName` | Sim | O nome do parceiro, de 1 a 100 caracteres. Uma letra acentuada, e qualquer outro caractere fora do ASCII simples, conta como dois ou mais. Um nome mais longo é recusado. O nome é único no seu tenant, e a comparação ignora maiúsculas e minúsculas. |
| `permissions` | Sim | Uma ou mais entradas, cada uma com seus próprios `product`, `resources` e `actions`. Cada entrada precisa de pelo menos um recurso e uma ação. |
| `scope` | Sim, para cada produto cujo catálogo de escopo declara dimensões | Uma entrada por restrição: `product`, `field` e `values`. `field` é o `name` de uma dimensão no catálogo de escopo do produto. |
| `ipAllowlist` | Não | A lista de IPs permitidos própria do parceiro. Cada entrada tem um `cidr` e uma `description` opcional de até 255 caracteres. |
| `validFrom` | Não | O início da janela de validade, como um instante RFC 3339. Ausente significa sem data de início. |
| `validUntil` | Não | O fim da janela de validade, como um instante RFC 3339. Ausente significa sem data de fim. |
| `state` | Não aceito | `active` ou `suspended`. Todo parceiro novo é `active`. Você o altera com `PATCH`. |

A resposta também traz `id`, `applicationsCount`, `createdAt` e `updatedAt`.

Regras que valem para os campos:

* `product` é o slug de produto que o catálogo de escopo do produto traz, como `plugin-br-pix-jd`.
* Escreva `actions` como verbos HTTP em minúsculas: `get`, `post`, `put`, `patch`, `delete`.
* `resources` × `actions` é um produto cartesiano completo. Para dar ações diferentes em recursos diferentes, envie mais de uma entrada para o mesmo produto.
* O Access Manager recusa o curinga `*` em `resources`, `actions` e `values`. Liste os itens.
* Um produto em `scope` também deve estar em `permissions`.
* Um produto cujo catálogo de escopo declara dimensões precisa de pelo menos uma entrada de escopo em cada parceiro com permissões nesse produto. A exceção é uma entrada de permissões que tem apenas permissões que o produto reserva para parceiros: ela não precisa de escopo, e vale para o tenant inteiro. Sem uma entrada de escopo, o Access Manager recusa criar ou alterar o parceiro, com `IDE-1060`. Um parceiro guardado sem ela antes desta regra é recusado com `403` em toda requisição a esse produto, até você adicionar uma entrada de escopo.
* Uma dimensão que o catálogo marca como `required` precisa de uma entrada de escopo em cada parceiro com permissões nesse produto, ou o Access Manager recusa com `IDE-0001`. Uma dimensão sem `multi` aceita apenas um valor, ou o Access Manager recusa com `IDE-0002`.
* Para uma dimensão que o catálogo marca como `explicit`, uma permissão na coleção dessa dimensão precisa de uma entrada de escopo que liste os IDs dela. Sem ela, o Access Manager recusa com `IDE-1052`. O parceiro alcança só os IDs que você lista.
* O Access Manager não confere se os `values` existem no produto. Use os identificadores que a própria API do produto retorna.
* `state` é `active` ou `suspended`, nunca `expired`. Depois de `validUntil`, uma leitura ainda retorna o estado guardado.
* Depois da data `validUntil` do parceiro, o Access Manager recusa as requisições dele, também com um token que ele já tem, e recusa tokens novos.

## O campo de lista de IPs permitidos

***

`ipAllowlist` tem três significados no `PATCH`:

| Você envia | O que acontece |
| - | - |
| O campo omitido | A lista guardada continua como está. |
| `null` | A lista própria do parceiro é excluída. O parceiro volta para a lista do seu tenant. |
| Uma lista de entradas | Estas entradas substituem a lista própria do parceiro. |
| `[]` | Recusado com `IDE-1048`. |

Cada entrada da lista própria do parceiro deve ser um intervalo IPv4 de `/24` ou mais estreito, ou um intervalo IPv6 de `/48` ou mais estreito. Uma entrada mais ampla é recusada com `IDE-1052`. Uma entrada que o parceiro já tem não é verificada de novo.

No `POST`, omita o campo ou envie `null` para usar a lista do seu tenant.

Quando um parceiro tem uma lista de IPs própria, essa lista substitui a lista de IPs do tenant nas requisições do parceiro.

`validFrom` e `validUntil` funcionam de forma parecida no `PATCH`. Omita um limite para mantê-lo, envie um instante para defini-lo ou envie `null` para removê-lo.

## Exemplos

***

Troque os placeholders pela URL base da sua Identity API, pelo seu bearer token e por identificadores do seu próprio deploy.

```bash Create a partner theme={null}
IDENTITY_BASE_URL="https://identity.<your-domain>"   # your Identity API base URL
IDENTITY_BEARER_TOKEN="paste-your-access-token-here"

curl -sS -X POST "${IDENTITY_BASE_URL}/v1/partners" \
  -H "Authorization: Bearer ${IDENTITY_BEARER_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "displayName": "Partner A",
    "permissions": [
      { "product": "plugin-br-pix-jd", "resources": ["entries"], "actions": ["get", "post"] }
    ],
    "scope": [
      { "product": "plugin-br-pix-jd", "field": "participantId", "values": ["12345678"] }
    ],
    "ipAllowlist": [
      { "cidr": "203.0.113.10", "description": "Partner A gateway" }
    ]
  }'
```

```bash Create its application theme={null}
IDENTITY_BASE_URL="https://identity.<your-domain>"   # your Identity API base URL
IDENTITY_BEARER_TOKEN="paste-your-access-token-here"
PARTNER_ID="paste-the-partner-id-here"

curl -sS -X POST "${IDENTITY_BASE_URL}/v1/applications" \
  -H "Authorization: Bearer ${IDENTITY_BEARER_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "target": "plugin-br-pix-jd",
    "description": "Partner A access to Pix JD",
    "partnerId": "'"${PARTNER_ID}"'"
  }'
```

```bash Suspend it theme={null}
IDENTITY_BASE_URL="https://identity.<your-domain>"   # your Identity API base URL
IDENTITY_BEARER_TOKEN="paste-your-access-token-here"
PARTNER_ID="paste-the-partner-id-here"

curl -sS -X PATCH "${IDENTITY_BASE_URL}/v1/partners/${PARTNER_ID}" \
  -H "Authorization: Bearer ${IDENTITY_BEARER_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{ "state": "suspended" }'
```

```bash Go back to the tenant's IP list theme={null}
IDENTITY_BASE_URL="https://identity.<your-domain>"   # your Identity API base URL
IDENTITY_BEARER_TOKEN="paste-your-access-token-here"
PARTNER_ID="paste-the-partner-id-here"

curl -sS -X PATCH "${IDENTITY_BASE_URL}/v1/partners/${PARTNER_ID}" \
  -H "Authorization: Bearer ${IDENTITY_BEARER_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{ "ipAllowlist": null }'
```

## Criar as aplicações do parceiro

***

Um parceiro chama um produto com uma aplicação que pertence a ele. Depois de criar o parceiro:

1. Crie uma aplicação com [Criar uma aplicação](https://docs.lerian.studio/pt/reference/platform/access-manager/create-an-application.md). Envie o `id` do parceiro em `partnerId` e o slug do produto em `target`, como `plugin-br-pix-jd`.
2. A Identity API retorna o client secret somente na resposta que cria a aplicação. Guarde-o nesse momento. Se você perder o secret, exclua a aplicação e crie uma nova.
3. Envie o client ID e o secret ao parceiro por um canal seguro.
4. Repita os passos 1 a 3 para cada produto que o parceiro chama. Crie uma aplicação por produto.

Para listar as aplicações de um parceiro, envie o `id` dele no parâmetro de consulta `partnerId` de [Listar aplicações](https://docs.lerian.studio/pt/reference/platform/access-manager/list-applications.md). Se `partnerId` não nomear um parceiro do seu tenant, as duas operações retornam `404` com `IDE-1046`.

## Alterar, suspender ou excluir um parceiro

***

* No `PATCH`, envie apenas os campos que você altera. Uma lista `permissions` ou `scope` substitui a lista guardada inteira. Leia o parceiro antes e depois envie a nova lista completa.
* Para suspender um parceiro, envie `"state": "suspended"`. Para reativá-lo, envie `"state": "active"`.
* Suspender um parceiro no Access Manager interrompe o acesso dele, inclusive os tokens que ele já tem. Reativar o parceiro dentro da janela de validade dele restaura o acesso com as mesmas credenciais.
* [Quando uma alteração vale](https://docs.lerian.studio/pt/platform/access-manager/features/partners/overview#when-a-change-applies) diz quando o parceiro vê uma alteração de permissões ou de escopo.
* Você não pode excluir um parceiro que ainda tem aplicações. A resposta é `409` com `IDE-1049`, e a lista `errors` dela nomeia cada aplicação que bloqueia, com o client ID dela. Exclua essas aplicações antes.
* Excluir uma aplicação faz os tokens dela pararem de funcionar.

## Códigos de erro

***

Erros nas operações de parceiro:

| Código | Status | Título | Quando |
| - | - | - | - |
| `IDE-0001` | 400 | Missing Fields in Request | Falta um campo obrigatório, ou o escopo não tem entrada para uma dimensão que o produto exige. |
| `IDE-0002` | 400 | Invalid Field Type | Uma dimensão que aceita um valor recebeu vários. |
| `IDE-0036` | 400 | Invalid IP Allowlist Entry | Uma entrada de `ipAllowlist` não é um endereço ou uma faixa CIDR válida. |
| `IDE-1040` | 409 | Partner Display Name Already Exists | Outro parceiro do seu tenant tem o mesmo `displayName`. |
| `IDE-1042` | 400 | Unknown Scope Field | Um `field` de escopo não está no catálogo de escopo do produto, ou o produto não tem catálogo de escopo. |
| `IDE-1043` | 400 | Permission Above Product Ceiling | Uma permissão está acima do teto do produto no seu tenant. |
| `IDE-1044` | 400 | Scope Without Permissions | Um produto está em `scope`, mas não em `permissions`. |
| `IDE-1045` | 400 | Invalid Validity Window | `validUntil` não é posterior a `validFrom`. |
| `IDE-1046` | 404 | Partner Not Found | Não existe parceiro com este `id` no seu tenant. |
| `IDE-1047` | 400 | Wildcard Not Allowed | `*` está em `resources`, `actions` ou `values`. |
| `IDE-1048` | 400 | Empty IP Allowlist | `ipAllowlist` é um array vazio. |
| `IDE-1049` | 409 | Partner Has Applications | O parceiro ainda tem aplicações, então não pode ser excluído. |
| `IDE-1050` | 400 | Duplicate IP Allowlist Entry | A mesma rede aparece duas vezes em `ipAllowlist`. |
| `IDE-1052` | 400 | Partner Rejected | O provedor de identidade recusou o parceiro por outro motivo, por exemplo uma permissão na coleção de uma dimensão `explicit` sem os IDs dela. A mensagem repete esse motivo. |
| `IDE-1053` | 404 | Scope Catalog Not Found | O produto não publicou um catálogo de escopo. |
| `IDE-1054` | 400 | Product Not Ready For Partners | Uma permissão nomeia um produto que não publicou o catálogo de escopo dele. |
| `IDE-1055` | 400 | Product Not Opted In To Partners | Uma permissão nomeia um produto cujo catálogo de escopo não aceita parceiros. |
| `IDE-1056` | 400 | Partner Write Exceeds Its Scope | Uma permissão de escrita atua em um nível mais amplo que o escopo do parceiro. |
| `IDE-1057` | 400 | Partner Read Rejected | O provedor de identidade recusou a leitura do teto, por exemplo para um produto desconhecido. |
| `IDE-1060` | 400 | Partner Product Without Scope | Uma permissão que o produto não reserva para parceiros nomeia um produto cujo catálogo de escopo declara dimensões, e `scope` não tem entrada para esse produto. No `PATCH`, remover a última entrada de escopo de um produto que mantém as permissões também é recusado. |

Para qualquer outro código, consulte a [lista de erros do Access Manager](https://docs.lerian.studio/pt/reference/platform/access-manager/access-manager-error-list.md).


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