<!-- llms.txt: https://workos.com/llms.txt -->

# Relay

## Overview

Relay calls third-party APIs on your users' behalf without exposing their
credentials to your application. Send the request to WorkOS, and relay attaches
the user's credential server-side and streams the provider's response back.

> **Note:** Relay is in early access. Contact support
> [via email](mailto:support@workos.com) or Slack to request access for your
> team.

Relay is a forward HTTP proxy built for AI agents and other untrusted
runtimes. With [access tokens](https://workos.com/docs/pipes#fetching-access-tokens), your
infrastructure fetches a provider access token and calls the provider directly,
so the token exists inside the calling environment, where it can be copied,
logged, or leaked. With relay, the provider credential never leaves WorkOS: the
agent authenticates with your WorkOS API key and names the user it acts for.

> **Note:** Relay removes provider credentials from the calling environment, not the
> WorkOS API key. That key authenticates every WorkOS API call for the
> environment, so treat it as a secret even in a sandbox: inject it at request
> time rather than baking it into agent-visible code or prompts, and rotate it
> from the *API Keys* section of the dashboard if a runtime is compromised.

## How it works

Every proxied request follows the same lifecycle:

1. **Authenticate.** Your WorkOS API key is verified and determines the
   environment. The key is stripped from the request and is never sent upstream.
2. **Resolve the user.** The `X-Relay-User` header identifies the user the
   request acts on behalf of, scoped by `X-Relay-Organization` when the
   connection belongs to an organization.
3. **Look up the connected account.** WorkOS finds the user's Pipes connection
   for the provider you named. If the user hasn't connected, or needs to
   reconnect, relay returns a `402` response.
4. **Resolve the credential.** WorkOS retrieves and refreshes OAuth access
   tokens, retrieves stored API keys, or mints access tokens from stored client
   credentials, depending on how the account is connected.
5. **Inject and forward.** Relay control headers, cookies, and forwarding
   metadata are stripped, the provider credential is injected into the
   provider's configured request header, and the request is forwarded over
   HTTPS.
6. **Stream the response.** The provider's status, headers, and body are streamed
   back verbatim, with an added `X-Relay-Upstream-Status` header.

## Before you begin

Relay builds on your existing Pipes setup. You need:

- A WorkOS API key for the environment, from the
  [API Keys](https://dashboard.workos.com/environment/api-keys) section of the
  WorkOS Dashboard.
- The target provider enabled for your environment, configured in the
  [Pipes](https://dashboard.workos.com/environment/pipes) section of the
  dashboard or through the
  [data integration API](https://workos.com/docs/reference/pipes/data-integration/create).
- A connected account for the user, created through the provider's OAuth flow,
  by entering an [API key](https://workos.com/docs/pipes/api-keys), or with the
  [client credentials endpoint](https://workos.com/docs/reference/pipes/connected-account/upsert-client-credentials).

Relay uses the connected account's authentication method—OAuth, API key, or
client credentials—without changing the relay request format. The provider's
Relay configuration determines which methods it accepts and how the credential
is presented upstream.

## Making requests

The base URL is `https://api.workos.com/relay`, and any HTTP method is
accepted. To convert a direct provider call into a proxied one:

1. Keep the method, body, and content headers as they are.
2. Send the request to the relay base URL, and move the original URL into the
   `X-Relay-URL` header.
3. Authenticate with your WorkOS API key in `Authorization`.
4. Name the user in `X-Relay-User`, adding `X-Relay-Organization` for
   organization-scoped connections.

### Request headers

| Header                 | Required         | Description                                                                                                                                                             |
| ---------------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Authorization`        | Yes              | `Bearer` followed by your WorkOS API key. Determines the environment. Never forwarded to the provider.                                                                  |
| `X-Relay-User`         | Yes              | The ID of the user the request acts on behalf of, for example `user_01EHZ…`. Must belong to the API key's environment.                                                  |
| `X-Relay-Organization` | Conditional      | The organization the connection was authorized under, for example `org_01KV9…`. Required when the connection is organization-scoped, and must be omitted when it isn't. |
| `X-Relay-URL`          | URL routing only | The full upstream URL, including path and query string. Must use HTTPS.                                                                                                 |
| `X-Relay-Provider`     | No               | The provider slug to relay to, for example `github`. Optional with URL routing, where the provider is otherwise resolved from the host.                                 |

All other request headers, including `Content-Type`, `Accept`, and
provider-specific headers, are forwarded unchanged. See
[limits and behavior](#limits-and-behavior) for the headers that are stripped.

### URL routing

Put the complete upstream URL in `X-Relay-URL`. The provider is resolved from the
URL's host, so your code keeps working with the provider's real URLs. Name the
provider explicitly with `X-Relay-Provider` when the host is ambiguous, or when
you would rather not depend on host inference.

:::code-group

```bash language="curl"
curl --request GET https://api.workos.com/relay \
  --header "Authorization: Bearer sk_example_123456789" \
  --header "X-Relay-URL: https://api.github.com/user/repos?per_page=5" \
  --header "X-Relay-User: user_01EHZNVPK3SFK441A1RGBFSHRT" \
  --header "X-Relay-Organization: org_01EHZNVPK3SFK441A1RGBFSHRT"
```

:::

### Path routing

Alternatively, prefix the provider's API path with the relay base URL and
the provider's slug. The slug in the path selects the provider, and the path and
query string are appended to the provider's default API host, so
`/relay/github/user` proxies to
`https://api.github.com/user`.

:::code-group

```bash language="curl"
curl --request GET "https://api.workos.com/relay/github/user/repos?per_page=5" \
  --header "Authorization: Bearer sk_example_123456789" \
  --header "X-Relay-User: user_01EHZNVPK3SFK441A1RGBFSHRT" \
  --header "X-Relay-Organization: org_01EHZNVPK3SFK441A1RGBFSHRT"
```

:::

URL routing is the better default: it can reach any of a provider's
[allowed hosts](#supported-providers) rather than only the default one, and it
keeps the provider's own URLs intact in your code and logs.

## Examples

### Query Linear

:::code-group

```bash language="curl"
curl --request POST https://api.workos.com/relay \
  --header "Authorization: Bearer sk_example_123456789" \
  --header "X-Relay-URL: https://api.linear.app/graphql" \
  --header "X-Relay-User: user_01EHZNVPK3SFK441A1RGBFSHRT" \
  --header "X-Relay-Organization: org_01EHZNVPK3SFK441A1RGBFSHRT" \
  --header "Content-Type: application/json" \
  --data '{"query": "{ viewer { id name email } }"}'
```

:::

### Post a Slack message

:::code-group

```bash language="curl"
curl --request POST https://api.workos.com/relay \
  --header "Authorization: Bearer sk_example_123456789" \
  --header "X-Relay-URL: https://slack.com/api/chat.postMessage" \
  --header "X-Relay-User: user_01EHZNVPK3SFK441A1RGBFSHRT" \
  --header "X-Relay-Organization: org_01EHZNVPK3SFK441A1RGBFSHRT" \
  --header "Content-Type: application/json" \
  --data '{"channel": "C01XXXXXXXX", "text": "Hello from Pipes Relay"}'
```

:::

## Organization scoping

Pipes connections are either scoped to an organization or user-only, and the
connection lookup requires an exact match on that scope:

- If the user authorized the provider under an organization, requests must
  include `X-Relay-Organization` with that organization's ID.
- If the user authorized the provider without an organization, the header must be
  omitted.

> **Note:** A scope mismatch in either direction returns the same `402`
> `relay_authorization_required` response as a user who never connected at all.
> If a connected user keeps getting a `402`, check that the
> `X-Relay-Organization` header matches the organization on their connected
> account before asking them to re-authorize.

## Handling authorization

When the user has no usable connection for the provider—they never connected,
their OAuth grant was revoked, or their token can no longer be refreshed—the
response is `402 Payment Required`:

:::code-group

```json language="json"
{
  "code": "relay_authorization_required",
  "connection": "github",
  "message": "User has not authorized provider \"github\"",
  "authorization_url": "https://github.com/login/oauth/authorize?client_id=..."
}
```

:::

For OAuth connections, surface the `authorization_url`, let the user complete
the provider's authorization flow, then retry the original request.

`authorization_url` is `null` for API key and client credentials connections.
Collect or rotate those credentials through the [Pipes widget](https://workos.com/docs/widgets/pipes),
the [upsert API key endpoint](https://workos.com/docs/reference/pipes/connected-account/upsert-api-key),
or the [client credentials endpoint](https://workos.com/docs/reference/pipes/connected-account/upsert-client-credentials),
then retry. It can also be `null` when a provider's OAuth configuration is
incomplete.

> **Note:** Authorization-required responses use `402`, not `401` or `403`, so they can't
> be confused with a WorkOS authentication failure (`401`) or a
> provider-returned `401` or `403` passed through from upstream.

## Responses

On success you receive the provider's status code, headers, and body exactly as
the provider sent them, streamed as they arrive. Provider errors are passed
through untouched, so a GitHub `404` comes back as a `404` with GitHub's own
error body.

Every proxied response carries an `X-Relay-Upstream-Status` header with the
provider's status code. Its presence means the request reached the provider, so
you can distinguish an upstream `404` from a relay `404` such as an unknown
provider.

## Limits and behavior

| Behavior                  | Detail                                                                                                                                                                                                                        |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Request body              | Forwarded byte-for-byte, up to 5 MB. `GET` and `HEAD` requests send no body.                                                                                                                                                  |
| Upstream timeout          | 30 seconds. A provider that doesn't respond in time yields `502 relay_upstream_error`.                                                                                                                                        |
| HTTPS only                | `X-Relay-URL` must use HTTPS. Credentials are never injected into a plaintext request.                                                                                                                                        |
| Host allowlist            | Requests can only target a supported provider's allowed hosts. Anything else is rejected before the request is sent.                                                                                                          |
| Redirects                 | Not followed. Redirect responses are returned as-is.                                                                                                                                                                          |
| Stripped request headers  | Hop-by-hop headers such as `Connection` and `Transfer-Encoding`, `Cookie`, forwarding metadata such as `X-Forwarded-*`, `Via`, and `X-Real-IP`, your `Authorization` header, and anything prefixed `X-Relay-` or `X-WorkOS-`. |
| Stripped response headers | Hop-by-hop headers and `Set-Cookie`. Compressed bodies are decoded in transit, so `Content-Encoding` and `Content-Length` may be removed.                                                                                     |

## Supported providers

Relay supports the active providers below. With path routing, the request goes
to the provider's base API host. With URL routing, any listed host is allowed.
The provider must also be enabled for your environment.

The Authentication column shows the methods explicitly configured for each
provider. Relay can also mint tokens for eligible client credentials connections;
contact support to confirm provider eligibility during early access.

> **Note:** [Custom providers](https://workos.com/docs/pipes/custom-providers) aren't yet supported by Relay.

| Provider                      | Slug                         | Authentication | Allowed hosts                                  |
| ----------------------------- | ---------------------------- | -------------- | ---------------------------------------------- |
| Acuity Scheduling             | `acuity-scheduling`          | OAuth          | `acuityscheduling.com`                         |
| Addepar                       | `addepar`                    | OAuth          | `api.addepar.com`                              |
| Adobe                         | `adobe`                      | OAuth          | `ims-na1.adobelogin.com`                       |
| Aimfox                        | `aimfox`                     | OAuth, API key | `api.aimfox.com`                               |
| Aircall                       | `aircall`                    | OAuth          | `api.aircall.io`                               |
| Airtable                      | `airtable`                   | OAuth, API key | `api.airtable.com`                             |
| Anthropic                     | `anthropic`                  | API key        | `api.anthropic.com`                            |
| Apaleo                        | `apaleo`                     | OAuth          | `api.apaleo.com`                               |
| Apollo.io                     | `apollo-oauth`               | OAuth, API key | `app.apollo.io`                                |
| Asana                         | `asana`                      | OAuth, API key | `app.asana.com`                                |
| Ashby                         | `ashby`                      | API key        | `api.ashbyhq.com`                              |
| Atlassian                     | `atlassian`                  | OAuth, API key | `api.atlassian.com`                            |
| Attio                         | `attio`                      | OAuth, API key | `api.attio.com`                                |
| Autodesk                      | `autodesk`                   | OAuth          | `developer.api.autodesk.com`                   |
| BambooHR                      | `bamboohr`                   | OAuth          | `api.bamboohr.com`                             |
| beehiiv                       | `beehiiv`                    | API key        | `api.beehiiv.com`                              |
| Bing Webmasters               | `bing-webmasters`            | OAuth          | `www.bing.com`                                 |
| BitBucket                     | `bitbucket`                  | OAuth          | `api.bitbucket.org`                            |
| Bitly                         | `bitly`                      | OAuth, API key | `api-ssl.bitly.com`                            |
| BoldSign                      | `boldsign`                   | OAuth, API key | `api.boldsign.com`                             |
| Box                           | `box`                        | OAuth          | `api.box.com`, `upload.box.com`                |
| Braintree                     | `braintree`                  | OAuth          | `api.braintreegateway.com`                     |
| Brandfetch                    | `brandfetch`                 | API key        | `api.brandfetch.io`                            |
| Brex                          | `brex`                       | OAuth, API key | `platform.brexapis.com`                        |
| Buffer                        | `buffer`                     | OAuth          | `api.buffer.com`                               |
| Cal.com                       | `cal-dot-com`                | OAuth, API key | `api.cal.com`                                  |
| Calendly                      | `calendly`                   | OAuth, API key | `api.calendly.com`                             |
| Candis                        | `candis`                     | OAuth          | `api.candis.io`                                |
| Canva                         | `canva`                      | OAuth          | `api.canva.com`                                |
| CircleCI                      | `circleci`                   | API key        | `circleci.com`                                 |
| Clerk                         | `clerk`                      | API key        | `api.clerk.com`                                |
| CleverReach                   | `cleverreach`                | OAuth          | `rest.cleverreach.com`                         |
| ClickUp                       | `clickup`                    | OAuth, API key | `api.clickup.com`                              |
| Close                         | `close`                      | OAuth, API key | `api.close.com`                                |
| Cloudbeds                     | `cloudbeds`                  | OAuth, API key | `api.cloudbeds.com`, `hotels.cloudbeds.com`    |
| Cloudflare                    | `cloudflare`                 | OAuth, API key | `api.cloudflare.com`                           |
| Cohere                        | `cohere`                     | API key        | `api.cohere.com`                               |
| Confluence                    | `confluence`                 | OAuth          | `api.atlassian.com`                            |
| Constant Contact              | `constant-contact`           | OAuth          | `api.cc.email`                                 |
| Conta Azul                    | `conta-azul`                 | OAuth          | `api-v2.contaazul.com`                         |
| Contentful                    | `contentful`                 | OAuth          | `api.contentful.com`                           |
| Copper                        | `copper`                     | OAuth          | `api.copper.com`                               |
| Crowdin                       | `crowdin`                    | OAuth          | `api.crowdin.com`                              |
| Datadog                       | `datadog`                    | OAuth          | `api.datadoghq.com`                            |
| DATEV                         | `datev`                      | OAuth          | `api.datev.de`                                 |
| Deel                          | `deel`                       | OAuth, API key | `api.letsdeel.com`                             |
| Deepgram                      | `deepgram`                   | API key        | `api.deepgram.com`                             |
| DeepSeek                      | `deepseek`                   | API key        | `api.deepseek.com`                             |
| Dialpad                       | `dialpad`                    | OAuth, API key | `dialpad.com`                                  |
| DigitalOcean                  | `digitalocean`               | OAuth, API key | `api.digitalocean.com`                         |
| Digits                        | `digits`                     | OAuth          | `connect.digits.com`                           |
| Discord                       | `discord`                    | OAuth, API key | `discord.com`                                  |
| Dovetail                      | `dovetail`                   | API key        | `dovetail.com`                                 |
| DrChrono                      | `drchrono`                   | OAuth          | `app.drchrono.com`                             |
| Dropbox                       | `dropbox`                    | OAuth          | `api.dropboxapi.com`, `content.dropboxapi.com` |
| Dropbox Sign                  | `dropbox-sign`               | OAuth, API key | `api.hellosign.com`                            |
| ElevenLabs                    | `elevenlabs`                 | API key        | `api.elevenlabs.io`                            |
| Employment Hero               | `employment-hero`            | OAuth          | `api.employmenthero.com`                       |
| Envoy                         | `envoy`                      | OAuth, API key | `api.envoy.com`                                |
| Eventbrite                    | `eventbrite`                 | OAuth, API key | `www.eventbriteapi.com`                        |
| Exa                           | `exa`                        | API key        | `api.exa.ai`                                   |
| Factorial                     | `factorial`                  | OAuth, API key | `api.factorialhr.com`                          |
| Fathom                        | `fathom`                     | OAuth, API key | `api.fathom.ai`                                |
| Figma                         | `figma`                      | OAuth, API key | `api.figma.com`                                |
| Firecrawl                     | `firecrawl`                  | API key        | `api.firecrawl.dev`                            |
| Fireworks                     | `fireworks`                  | API key        | `api.fireworks.ai`                             |
| Fly.io                        | `fly-io`                     | OAuth, API key | `api.machines.dev`                             |
| Fortnox                       | `fortnox`                    | OAuth          | `api.fortnox.se`                               |
| Frame.io                      | `frame-io`                   | OAuth, API key | `api.frame.io`                                 |
| Frame.io V4                   | `frame-io-v4`                | OAuth, API key | `api.frame.io`                                 |
| FreeAgent                     | `freeagent`                  | OAuth          | `api.freeagent.com`                            |
| FreshBooks                    | `freshbooks`                 | OAuth          | `api.freshbooks.com`                           |
| Front                         | `front`                      | OAuth, API key | `api2.frontapp.com`                            |
| G2                            | `g2`                         | API key        | `data.g2.com`                                  |
| Gamma                         | `gamma`                      | OAuth, API key | `public-api.gamma.app`                         |
| GitHub                        | `github`                     | OAuth, API key | `api.github.com`                               |
| GitLab                        | `gitlab`                     | OAuth, API key | `gitlab.com`                                   |
| Gmail                         | `gmail`                      | OAuth          | `gmail.googleapis.com`                         |
| Google                        | `google`                     | OAuth          | `www.googleapis.com`                           |
| Google BigQuery               | `bigquery`                   | OAuth          | `bigquery.googleapis.com`                      |
| Google Calendar               | `google-calendar`            | OAuth          | `www.googleapis.com`                           |
| Google Docs                   | `google-docs`                | OAuth          | `www.googleapis.com`                           |
| Google Drive                  | `google-drive`               | OAuth          | `www.googleapis.com`                           |
| Google Gemini                 | `google-gemini`              | OAuth, API key | `generativelanguage.googleapis.com`            |
| Google Meet                   | `google-meet`                | OAuth          | `www.googleapis.com`                           |
| Google Sheets                 | `google-sheets`              | OAuth          | `www.googleapis.com`                           |
| Google Slides                 | `google-slides`              | OAuth          | `www.googleapis.com`                           |
| Grain                         | `grain`                      | OAuth, API key | `api.grain.com`                                |
| Granola                       | `granola`                    | API key        | `public-api.granola.ai`                        |
| Greenhouse                    | `greenhouse`                 | API key        | `harvest.greenhouse.io`                        |
| Greenhouse (Ingestion API)    | `greenhouse-ingestion`       | OAuth          | `api.greenhouse.io`                            |
| Gusto                         | `gusto`                      | OAuth          | `api.gusto.com`                                |
| Harvest                       | `harvest`                    | OAuth, API key | `api.harvestapp.com`                           |
| Health Gorilla                | `health-gorilla`             | OAuth          | `api.healthgorilla.com`                        |
| Help Scout                    | `helpscout`                  | OAuth          | `api.helpscout.net`                            |
| HeyGen                        | `heygen`                     | OAuth, API key | `api2.heygen.com`                              |
| HOVER                         | `hover`                      | OAuth          | `api.hover.to`                                 |
| HubSpot                       | `hubspot`                    | OAuth, API key | `api.hubapi.com`                               |
| Hugging Face                  | `hugging-face`               | OAuth          | `huggingface.co`                               |
| incident.io                   | `incident-io`                | API key        | `api.incident.io`                              |
| Intercom                      | `intercom`                   | OAuth, API key | `api.intercom.io`                              |
| Intralinks                    | `intralinks`                 | OAuth          | `api.intralinks.com`                           |
| Jira                          | `jira`                       | OAuth          | `api.atlassian.com`                            |
| Jobber                        | `jobber`                     | OAuth          | `api.getjobber.com`                            |
| Kakao                         | `kakao`                      | OAuth, API key | `kapi.kakao.com`                               |
| Keap                          | `keap`                       | OAuth          | `api.infusionsoft.com`                         |
| Kernel                        | `kernel`                     | API key        | `api.onkernel.com`                             |
| Klaviyo                       | `klaviyo`                    | OAuth, API key | `a.klaviyo.com`                                |
| LaunchDarkly                  | `launchdarkly`               | OAuth          | `app.launchdarkly.com`                         |
| Lever                         | `lever`                      | OAuth, API key | `api.lever.co`                                 |
| Linear                        | `linear`                     | OAuth, API key | `api.linear.app`                               |
| LinkedIn                      | `linkedin`                   | OAuth          | `api.linkedin.com`                             |
| Local Falcon                  | `local-falcon`               | API key        | `api.localfalcon.com`                          |
| Lokalise                      | `lokalise`                   | OAuth, API key | `api.lokalise.com`                             |
| Luma                          | `luma`                       | API key        | `public-api.luma.com`                          |
| Mailgun                       | `mailgun`                    | API key        | `api.eu.mailgun.net`, `api.mailgun.net`        |
| Manufact                      | `manufact`                   | API key        | `cloud.manufact.com`                           |
| Mem0                          | `mem0`                       | API key        | `api.mem0.ai`                                  |
| Mercury                       | `mercury`                    | OAuth, API key | `api.mercury.com`                              |
| Microsoft                     | `microsoft`                  | OAuth          | `graph.microsoft.com`                          |
| Microsoft OneDrive            | `microsoft-onedrive`         | OAuth          | `graph.microsoft.com`                          |
| Microsoft OneNote             | `microsoft-onenote`          | OAuth          | `graph.microsoft.com`                          |
| Microsoft Outlook             | `microsoft-outlook`          | OAuth          | `graph.microsoft.com`                          |
| Microsoft Outlook Calendar    | `microsoft-outlook-calendar` | OAuth          | `graph.microsoft.com`                          |
| Microsoft SharePoint          | `microsoft-sharepoint`       | OAuth          | `graph.microsoft.com`                          |
| Microsoft Teams               | `microsoft-teams`            | OAuth          | `graph.microsoft.com`                          |
| Microsoft To-Do               | `microsoft-todo`             | OAuth          | `graph.microsoft.com`                          |
| Miro                          | `miro`                       | OAuth, API key | `api.miro.com`, `miro.com`                     |
| Mollie                        | `mollie`                     | OAuth, API key | `api.mollie.com`                               |
| Monday.com                    | `monday`                     | OAuth, API key | `api.monday.com`                               |
| Motive                        | `motive`                     | OAuth, API key | `api.gomotive.com`, `api.keeptruckin.com`      |
| Mural                         | `mural`                      | OAuth          | `app.mural.co`                                 |
| Neon                          | `neon`                       | OAuth, API key | `console.neon.tech`                            |
| Netlify                       | `netlify`                    | OAuth, API key | `api.netlify.com`                              |
| ngrok                         | `ngrok`                      | API key        | `api.ngrok.com`                                |
| Notion                        | `notion`                     | OAuth, API key | `api.notion.com`                               |
| npm                           | `npm`                        | API key        | `registry.npmjs.org`                           |
| OpenAI                        | `openai`                     | API key        | `api.openai.com`                               |
| OpenRouter                    | `openrouter`                 | API key        | `openrouter.ai`                                |
| Orb                           | `orb`                        | API key        | `api.withorb.com`                              |
| Outreach                      | `outreach`                   | OAuth          | `api.outreach.io`                              |
| PagerDuty                     | `pagerduty`                  | OAuth, API key | `api.pagerduty.com`                            |
| PandaDoc                      | `pandadoc`                   | OAuth, API key | `api.pandadoc.com`                             |
| Pardot                        | `pardot`                     | OAuth          | `pi.demo.pardot.com`, `pi.pardot.com`          |
| PayPal                        | `paypal`                     | OAuth          | `api-m.paypal.com`                             |
| Pennylane                     | `pennylane`                  | OAuth, API key | `app.pennylane.com`                            |
| Perk                          | `perk`                       | OAuth, API key | `api.travelperk.com`                           |
| Perplexity                    | `perplexity`                 | API key        | `api.perplexity.ai`                            |
| Plain                         | `plain`                      | API key        | `core-api.uk.plain.com`                        |
| PlanetScale                   | `planetscale`                | OAuth          | `api.planetscale.com`                          |
| Podium                        | `podium`                     | OAuth          | `api.podium.com`                               |
| Postman                       | `postman`                    | API key        | `api.getpostman.com`                           |
| PreciseFP                     | `precisefp`                  | OAuth          | `app.precisefp.com`                            |
| Procore                       | `procore`                    | OAuth          | `api.procore.com`                              |
| Productboard                  | `productboard`               | OAuth, API key | `api.productboard.com`                         |
| QuickBooks                    | `quickbooks`                 | OAuth          | `quickbooks.api.intuit.com`                    |
| QuickBooks Time               | `tsheetsteam`                | OAuth          | `rest.tsheets.com`                             |
| Railway                       | `railway`                    | API key        | `backboard.railway.com`                        |
| Ramp                          | `ramp`                       | OAuth          | `api.ramp.com`                                 |
| Reapit                        | `reapit`                     | OAuth          | `platform.reapit.cloud`                        |
| Reddit                        | `reddit`                     | OAuth          | `oauth.reddit.com`                             |
| Render                        | `render`                     | API key        | `api.render.com`                               |
| Replicate                     | `replicate`                  | API key        | `api.replicate.com`                            |
| Resend                        | `resend`                     | API key        | `api.resend.com`                               |
| RingCentral                   | `ring-central`               | OAuth          | `platform.ringcentral.com`                     |
| Sage                          | `sage`                       | OAuth          | `api.accounting.sage.com`                      |
| Sage Intacct                  | `sage-intacct`               | OAuth          | `api.intacct.com`                              |
| Salesloft                     | `salesloft`                  | OAuth, API key | `api.salesloft.com`                            |
| Salesmsg                      | `salesmsg`                   | OAuth          | `api.salesmessage.com`                         |
| Segment                       | `segment`                    | API key        | `api.segmentapis.com`                          |
| Sellsy                        | `sellsy`                     | OAuth          | `api.sellsy.com`                               |
| SendGrid                      | `sendgrid`                   | API key        | `api.sendgrid.com`                             |
| Sentry                        | `sentry`                     | OAuth, API key | `sentry.io`                                    |
| Serval                        | `serval`                     | OAuth          | `public.api.serval.com`                        |
| ServiceM8                     | `servicem8`                  | OAuth, API key | `api.servicem8.com`                            |
| signNow                       | `signnow`                    | OAuth          | `api.signnow.com`                              |
| Slack                         | `slack`                      | OAuth          | `slack.com`                                    |
| Slack User                    | `slack-user`                 | OAuth          | `slack.com`                                    |
| Socket                        | `socket`                     | API key        | `api.socket.dev`                               |
| Spotify                       | `spotify`                    | OAuth          | `api.spotify.com`                              |
| Stripe                        | `stripe`                     | OAuth, API key | `api.stripe.com`                               |
| Stripe Connect                | `stripe-connect`             | OAuth, API key | `api.stripe.com`                               |
| SurveyMonkey                  | `survey-monkey`              | OAuth, API key | `api.surveymonkey.com`                         |
| Teamleader Focus              | `teamleader`                 | OAuth          | `api.focus.teamleader.eu`                      |
| Ticket Tailor                 | `ticket-tailor`              | API key        | `api.tickettailor.com`                         |
| TickTick                      | `ticktick`                   | OAuth          | `api.ticktick.com`                             |
| TikTok                        | `tiktok`                     | OAuth          | `open.tiktokapis.com`                          |
| Timely                        | `timely`                     | OAuth          | `api.timelyapp.com`                            |
| Todoist                       | `todoist`                    | OAuth          | `api.todoist.com`                              |
| Tremendous                    | `tremendous`                 | OAuth, API key | `api.tremendous.com`                           |
| TriNet HR Platform (Zenefits) | `zenefits`                   | OAuth          | `api.trinet.com`, `api.zenefits.com`           |
| Typeform                      | `typeform`                   | OAuth, API key | `api.typeform.com`                             |
| VideoAsk                      | `videoask`                   | OAuth          | `api.videoask.com`                             |
| Wave Accounting               | `wave-accounting`            | OAuth, API key | `gql.waveapps.com`                             |
| Wealthbox                     | `wealthbox`                  | OAuth, API key | `api.crmworkspace.com`                         |
| Webex                         | `webex`                      | OAuth, API key | `webexapis.com`                                |
| Webflow                       | `webflow`                    | OAuth, API key | `api.webflow.com`                              |
| WHOOP                         | `whoop`                      | OAuth          | `api.prod.whoop.com`                           |
| Wix                           | `wix`                        | OAuth          | `www.wixapis.com`                              |
| WorkOS                        | `workos`                     | API key        | `api.workos.com`                               |
| X.com                         | `x-com`                      | OAuth, API key | `api.twitter.com`, `api.x.com`                 |
| xAI                           | `xai`                        | API key        | `api.x.ai`                                     |
| Xero                          | `xero`                       | OAuth          | `api.xero.com`                                 |
| Zapier                        | `zapier`                     | OAuth          | `api.zapier.com`                               |
| Zendesk Sell                  | `zendesk-sell`               | OAuth, API key | `api.getbase.com`                              |
| Zeplin                        | `zeplin`                     | OAuth          | `api.zeplin.dev`                               |
| Zoom                          | `zoom`                       | OAuth          | `api.zoom.us`                                  |

## Error reference

Errors generated by relay are JSON objects with `code` and `message`
fields. Provider errors are passed through unchanged, so check for
`X-Relay-Upstream-Status` to tell the two apart.

| Status | Code                            | Meaning                                                                                                                            |
| ------ | ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `401`  | —                               | Missing or invalid WorkOS API key.                                                                                                 |
| `400`  | `relay_missing_url`             | URL routing was used but the `X-Relay-URL` header is absent.                                                                       |
| `400`  | `relay_invalid_url`             | `X-Relay-URL` isn't a valid URL or doesn't use HTTPS, or the resolved target host isn't one of the provider's allowed hosts.       |
| `400`  | `relay_user_required`           | The `X-Relay-User` header is absent.                                                                                               |
| `400`  | `relay_user_not_found`          | No user with that ID exists in the API key's environment.                                                                          |
| `400`  | `relay_provider_conflict`       | The path slug and the `X-Relay-Provider` header name different providers.                                                          |
| `400`  | `relay_credential_invalid`      | The stored credential can't be presented to the provider — it needs to be replaced.                                                |
| `402`  | `relay_authorization_required`  | The user has no usable connection for this provider, or the organization scope doesn't match. The `authorization_url` may be null. |
| `404`  | `relay_provider_not_found`      | The slug or the `X-Relay-URL` host doesn't match a supported provider, or the provider isn't enabled in this environment.          |
| `404`  | `relay_provider_not_configured` | The provider has no relay configuration for the way this account is connected.                                                     |
| `404`  | —                               | A generic `404` with no `code` field means relay isn't enabled for your team.                                                      |
| `502`  | `relay_credential_error`        | The user's credential couldn't be resolved, for a reason that re-authorization won't fix.                                          |
| `502`  | `relay_upstream_error`          | The provider was unreachable or timed out.                                                                                         |
