# Partners

Read your trading partners and how each one is configured: its connection, its envelopes, its webhooks, the transaction sets it exchanges in each direction, and its flows.

**Preview.** These endpoints are in preview. Their response shapes may change without notice while the configuration model settles, so pin nothing critical to them yet.

These endpoints are read-only. Creating and changing partners, connections, envelopes, webhooks, mappings and flows is done in the Tediware application, and this reference is how your code confirms that setup rather than guessing at it.

Both endpoints cover your whole organization, so both require a standard API key. Sandbox keys cannot reach them.

## No secrets, ever

Nothing here returns a credential. Passwords, passphrases, private keys, webhook secrets, sink tokens and API keys are absent from these responses, not masked. A test renders every serializer on this plane through a fully populated record and fails if any key matching those words appears at any depth, so the guarantee holds for the resources added to this plane later as well.

## Raw facts, not a verdict

There is no `ready` flag. You get flow status, whether a mapping or an implementation is attached, and whether a connection is provisioned, and you decide what that means for your integration. Concretely, a transaction set is usable when its setting exists for the direction you need, a mapping or implementation is attached to it, and the flow for that direction has `status: "active"`.

That split is deliberate: a computed flag would have to pick one definition of ready, and a shipping integration, a setup wizard and a monitoring check each want a different one.

## List Partners

```
GET /platform/partners
```

Returns your partners with a summary of what is attached to each, oldest first, so a page reads in the order they were set up.

```json
{
  "partners": [
    {
      "id": "8c2021f8-8310-4628-80f9-b578d4d68e11",
      "key": "ACME",
      "name": "Acme Foods",
      "connection": { "id": "a1b2c3d4-...", "name": "Acme SFTP", "kind": "sftp" },
      "inboundSets": ["810", "850"],
      "outboundSets": ["856", "997"],
      "flows": [
        { "direction": "inbound", "status": "active" },
        { "direction": "outbound", "status": "active" }
      ]
    }
  ],
  "pagination": {
    "hasMore": false,
    "nextCursor": null
  }
}
```

`inboundSets` and `outboundSets` are transaction set codes, sorted. `connection` is `null` when the partner has none assigned.

Cursor pagination works as it does everywhere else: `limit` (default 50, maximum 100) and `cursor`, and when `hasMore` is `true` pass `nextCursor` back as `cursor`.

```bash
curl "https://tediware.com/platform/partners" \
  -H "Authorization: Key your-api-key-here"
```

## Get a Partner

```
GET /platform/partners/:key
```

Returns one partner with its related records embedded in full, so a single request answers everything about how that partner is set up.

```json
{
  "id": "8c2021f8-8310-4628-80f9-b578d4d68e11",
  "key": "ACME",
  "name": "Acme Foods",
  "startingInterchangeControlNumber": 1000,
  "startingGroupControlNumber": 1000,
  "autoAcknowledgeInbound": true,
  "expectFunctionalAcknowledgments": true,
  "deliveryMethod": "webhook",
  "connection": {
    "id": "a1b2c3d4-...",
    "name": "Acme SFTP",
    "kind": "sftp",
    "provisioned": true,
    "host": "sftp.acme.example",
    "port": 22,
    "username": "tediware",
    "inboundDirectory": "/out",
    "outboundDirectory": "/in"
  },
  "internalEnvelope": {
    "id": "e1f2a3b4-...",
    "name": "Our identifiers",
    "external": false,
    "interchangeExtid": "YOURID",
    "interchangeExtidQualifier": "ZZ",
    "applicationCode": "YOURID",
    "segmentSeparator": "~",
    "elementSeparator": "*",
    "componentSeparator": ">"
  },
  "externalEnvelope": {
    "id": "e5f6a7b8-...",
    "name": "Acme identifiers",
    "external": true,
    "interchangeExtid": "ACMEID",
    "interchangeExtidQualifier": "ZZ",
    "applicationCode": "ACMEID",
    "segmentSeparator": "~",
    "elementSeparator": "*",
    "componentSeparator": ">"
  },
  "inboundWebhook": {
    "id": "w1b2c3d4-...",
    "name": "Acme inbound",
    "url": "https://example.com/hooks/tediware/inbound",
    "kind": "inbound",
    "contentType": "application/json"
  },
  "outboundWebhook": null,
  "errorWebhook": null,
  "transactionSets": [
    {
      "transactionSetIdentifier": "850",
      "direction": "inbound",
      "mapping": { "id": "m1b2c3d4-...", "name": "Acme 850 inbound" },
      "implementation": null,
      "directory": "/out"
    },
    {
      "transactionSetIdentifier": "856",
      "direction": "outbound",
      "mapping": { "id": "m5b6c7d8-...", "name": "Acme 856" },
      "implementation": { "id": "i1b2c3d4-...", "name": "Acme 856 4010" },
      "directory": "/in"
    }
  ],
  "flows": [
    { "id": "f1b2c3d4-...", "name": "Acme Inbound", "direction": "inbound", "status": "active" },
    { "id": "f5b6c7d8-...", "name": "Acme Outbound", "direction": "outbound", "status": "active" }
  ],
  "createdAt": "2026-05-14T10:02:11.004Z",
  "updatedAt": "2026-08-29T16:41:52.118Z"
}
```

Each embedded object carries its own `id` and is `null` when nothing is assigned. The embedded shape is the one each of those resources returns from its own endpoint (see the Configuration page), so code written against the embed works against the endpoint too.

`deliveryMethod` is `"webhook"` or `"poll"` and says how this partner's outcomes reach you. A `"poll"` partner has no webhooks assigned by design; read the feed instead. Flow `status` is `"active"` or `"pending"`, and only an active flow accepts traffic. The connection carries `provisioned`, and an AS2 connection also carries `as2Ready` and `as2SetupStatus`.

`transactionSets` names the document attached to each setting by reference (`{id, name}`) rather than embedding it. A mapping or an implementation is large, and the reference is what you need to confirm one is attached.

Partner keys are case-insensitive in the URL and are stored and returned uppercase. `GET /platform/partners/acme` and `GET /platform/partners/ACME` resolve the same partner.

```bash
curl "https://tediware.com/platform/partners/ACME" \
  -H "Authorization: Key your-api-key-here"
```

### Error Responses

```
| Status | Code         | Cause                                                                 |
|--------|--------------|-----------------------------------------------------------------------|
| 401    | unauthorized | The API key is missing or invalid                                     |
| 403    | forbidden    | The key is a sandbox key. These endpoints cover the whole organization |
| 404    | not_found    | No partner with that key exists in your organization (reason: partner) |
```

## The rest of the configuration

Connections, envelopes, webhooks, flows, mappings, implementations and sources each have their own list and show endpoints, described on the Configuration page. Every `{id, name}` reference above resolves there.

Writes are not planned for this plane in the near term. Setup stays in the application, where it has validation, a flow builder and an audit trail behind it.
