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

# Foundry integrations

> Connect external tools to Foundry from your organization settings using API keys, bearer tokens, basic auth, advanced login exchange, or custom OAuth providers for Ravenna workflows.

An integration is a connection to an outside tool. Each integration stores the sign-in details so your functions can talk to the tool, plus a link to the tool's documentation so Foundry knows what the tool can do.

Integrations are managed by **organization admins** in Settings. Once an integration is set up, anyone using Foundry can build functions on top of it.

***

## Where integrations live

Foundry uses two settings pages:

* **Settings → Integrations**. Create and manage custom API integrations. They appear in the **Custom** category alongside Ravenna's built-in integrations. Click **Create** to open the [Create integration modal](#create-one).
* **Settings → OAuth Providers**. Register OAuth providers that end users connect their own accounts to.

You can also see the list of integrations available to Foundry inside the Foundry app itself: it is the first level of the left sidebar. Organization admins get a **+** (**New integration**) button in the sidebar header that opens **Settings → Integrations** in a new tab to start a new integration.

Each row's overflow menu depends on the integration type:

* **Custom API integrations** show **Edit** (workspace members and admins) and **Delete** (workspace admins).
* **Native bridge integrations** show **Manage** (organization admins), which opens the same Settings sheet inline (credentials, resync, workspace access, and disconnect) without leaving Foundry.

***

## Custom API integrations

Use these for any tool with an API that uses a static credential (API key, bearer token, basic auth), a login/token exchange ([advanced auth](#advanced-auth)), or no auth at all.

### Create one

From **Settings → Integrations**, click **Create** to open the Create integration modal. The modal opens on a provider picker, and there are two paths from there:

* **Curated provider.** Pick from the searchable list of ready-to-configure providers (Asana, Box, Dropbox, Figma, HubSpot, Notion, Zoom, and more) and connect straight from there. See [Connect a curated provider](#connect-a-curated-provider).
* **Custom integration.** Click **Can't find it? Set up a custom integration** at the bottom of the picker for any API not in the curated list. See [Set up a custom integration](#set-up-a-custom-integration).

#### Connect a curated provider

Type in the search box or scroll the list, then click the provider. The **Connect** screen opens for that provider. When the provider supports more than one authentication method (OAuth 2.0, Bearer token, API key, Basic auth), a tab for each appears at the top, so pick the one that matches how you plan to authenticate. Fill in the credentials and click **Connect**.

Curated providers come pre-configured from Ravenna's catalog:

* **Base URL and test endpoint** are already set for you.
* **OAuth 2.0**: the authorization URL, token URL, and default scopes come from the catalog for the top providers, or are looked up from docs research at connect time for the rest. You only paste the **Client ID** and **Client Secret** from the OAuth app you registered with the provider, optionally override the scopes, and click **Connect**. Ravenna mints (or reuses) an org-level OAuth provider from those credentials, so there's no separate trip to **Settings → OAuth Providers**. Retrying a failed OAuth connection reuses the existing draft and org provider rather than creating a duplicate.
* **API key**: when the catalog knows where the key goes (for example an `X-API-Key` header), the **Key Name** and **Key Location** fields are prefilled and hidden, so you only paste the secret value. Ravenna verifies the key against the catalog's test endpoint before saving.
* **Bearer / Basic**: fill in the credential, and Ravenna verifies it against the catalog's test endpoint before saving. A bad credential never lands as connected.

Docs research doesn't run for curated providers. The catalog entry is the research, so a curated integration is docs-validated the moment it's created and functions can be generated on it right after Connect succeeds.

#### Set up a custom integration

If the API isn't in the curated list, click **Can't find it? Set up a custom integration** at the bottom of the picker. You'll be asked for the **API name** first. As you type, Ravenna searches Context7's documentation index and offers to auto-configure from any match, prefilling the docs URL and description. Click the **Advanced** option to fill in the details yourself, then click **Continue**.

After **Continue**, the **Connect** screen opens and Ravenna researches the documentation to learn how the tool works, including pagination, auth methods, rate limits, error handling, and versioning. When research detects which authentication method the API uses, it suggests the matching sign-in type. See [Auth type suggestions](#auth-type-suggestions) below.

Select the sign-in type from the **Authentication Method** dropdown and fill in the credentials. The dropdown supports **API key**, **Bearer token**, **Basic auth**, **OAuth 2.0** (an existing org OAuth provider from **Settings → OAuth Providers**, so this option only appears once your organization has one), **Advanced**, and **No auth**. You can also add **default headers** that should be sent with every request from this integration. These are useful for things like a tenant or account header.

Pick **Advanced** when the API needs more than a single static credential, for example a login request that exchanges credentials for a token, or credentials spread across headers, body, and query string. See [Advanced auth](#advanced-auth) below.

Click **Connect**. Ravenna runs a test call against the auth test endpoint (or the OAuth token exchange) and the integration becomes available to Foundry functions once it succeeds.

<Info>
  The best documentation link is one that goes straight to the API reference, not the marketing homepage. If the tool has an OpenAPI or Swagger link, use that.
</Info>

### Auth type suggestions

When the Research step detects how the API authenticates, the wizard pre-selects the matching sign-in type on the Auth step and shows a banner on the Research step explaining the suggestion:

* Documentation describing a bearer token or basic auth pre-selects **Bearer token** or **Basic auth**.
* Documentation describing a login/token-exchange step (credentials posted to a login endpoint in exchange for a session token or cookie) or credentials split across multiple non-standard fields pre-selects **Advanced**. When a login step was detected, the wizard also turns on the **Requires Login Exchange** toggle so you can configure the login call.
* Documentation stating the API has no authentication pre-selects **No auth**.

The suggestion is a starting point, not a lock. Change the sign-in type on the Auth step if it's wrong, and the wizard never overrides a type you've already picked yourself.

<Info>
  **OAuth 2.0 is never pre-selected.** Standard OAuth 2.0 grants (authorization code, client credentials, refresh token) are deliberately excluded from the suggestion, even when research finds them in the documentation. Choosing an [OAuth provider](#oauth-providers) is left to you.
</Info>

### Advanced auth

Most tools work with the single-credential auth types above. Choose **Advanced** when the API's authentication doesn't fit one of them:

* Credentials must first be exchanged for a token via a separate **login request** (Mosyle is a common example).
* The API needs **several credentials at once**, for example an access token header plus an email and password in the body.
* A credential goes somewhere the other types can't put it: a JSON body property, a query parameter, or a form field.

Advanced auth is available in two places: the **Auth** step of the **New Integration** wizard, and the **Configure** dialog of an existing custom integration. Both surfaces render the same form.

#### Auth fields

Define each credential as a row in the **Auth fields** table:

| Column | What it does |
| - | - |
| **Name** | The header name, JSON body property, query parameter, or form field name. |
| **Sensitive** | Marks the value as a secret. Sensitive values are write-only: they're saved encrypted in the vault and never returned to the browser. New rows default to sensitive. |
| **Value** | The credential itself. When editing an existing integration, leave a sensitive value blank to keep the stored credential unchanged. |
| **Location** | Where the field is attached: **Header**, **Body (JSON)**, **Query param**, or **Form field**. |
| **Send on** | Only shown when a login exchange is configured. **Login only** sends the field just on the login request; **Every request** also attaches it to every API call the integration makes. |

Without a login exchange, every field is sent directly on every request. That covers plain API-key-style auth at any location, plus multi-credential setups.

<Info>
  Values for **Body (JSON)** fields are typed as real JSON. `1234` is sent as a number, `true`/`false` as booleans, and `null` as null. Wrap a value in double quotes (`"0042"`) to force it to stay a string.
</Info>

#### Login exchange

Turn on **Requires Login Exchange** when credentials must first be exchanged for a token via a separate login request. Then configure:

* **Login request**. The login URL and HTTP method (**POST**, **GET**, or **PUT**).
* **Token response**. Where the exchanged token comes back: a **Response header** (give the header name) or the **Response body** (give a dot-path into the JSON, like `data.token`).
* **Token prefix**. A scheme prefix, like `Bearer`, that Ravenna strips from the returned token and re-adds when sending it on API calls.
* **Max token lifetime**. How long Ravenna caches the exchanged token before logging in again. If the login response includes its own expiry (`expires_in`), the provider's value takes precedence.

With a login exchange configured, fields marked **Login only** describe the login request, and the exchanged token authenticates the integration's API calls.

#### Presets, previews, and testing

* **Start from a preset**. The **API Key**, **Bearer**, and **Mosyle** presets pre-fill the form with a known-good shape. The Mosyle preset, for example, sets up the login URL, an `accessToken` header, and `email`/`password` body fields, so you only paste your credentials.
* **Previews**. Expand **Previews** to see the exact request the configuration produces, as a **curl** command or as **JSON**. Sensitive values are masked in previews. The preview uses the configured test endpoint path, so it matches what Test connection sends.
* **Test connection**. Runs a live authenticated request against the test endpoint, including the login exchange if one is configured, so you can verify the setup before saving.

For a Mosyle-style login exchange, the login request preview looks like this:

```bash theme={"system"}
curl -X POST 'https://businessapi.mosyle.com/v1/login' \
  -H 'accessToken: ••••••••' \
  -H 'Content-Type: application/json' \
  -d '{"email":"admin@example.com","password":"••••••••"}'
```

### Edit or delete later

From **Settings → Integrations**, click any custom integration's tile to open its connections view, then choose **Configure** from the connection's **⋯** menu. In **Configure** you can edit the basics and authentication, re-run docs research, or delete the integration. Delete a custom integration from **Configure** rather than with **Disconnect**. You'll need to remove or unpublish any functions using it before you can delete it.

<Info>
  Credentials are stored in Ravenna's secure vault. They're only used when a function runs and they're never shown to the AI that writes your function code.
</Info>

<Callout icon="book-open" color="#7C3AED">
  For a step-by-step walkthrough of the custom integration wizard, see [Set up a custom API integration](/guides/how-to/foundry/setup-custom-api) in the Foundry guide.
</Callout>

### Set up a custom integration from Copilot chat

You can also create a custom API integration by asking Copilot to add one. When Copilot creates a draft integration on your behalf, it renders an inline **setup card** in the conversation so you can finish the wizard without leaving chat. The card handles every auth type end-to-end: API key, bearer token, basic auth, Advanced, and OAuth 2.0.

The card advances through four stages:

<Steps>
  <Step title="Config">
    Confirm the API base URL, docs URL, and authentication type. Clicking **Continue** saves the draft integration and moves to the next stage. If you pick **No auth**, the card skips credentials and goes straight to validation.
  </Step>

  <Step title="Credentials">
    Enter the credential in a masked field on the card. The value is submitted directly to Ravenna's encrypted vault out-of-band. It never appears in the chat transcript, is never sent to the LLM, and is not stored in message history.

    For services that use basic auth with an API key in the username slot and no password (Stripe, Mailgun, Cursor), the card shows a single masked **API key** field instead of separate username and password fields. Paste the key there. Under the hood the integration still uses basic auth and Foundry sends a valid `Authorization: Basic` header with the key as the username.
  </Step>

  <Step title="Validation">
    Ravenna runs a live authenticated request against the auth-test endpoint discovered during docs research. "Connection succeeded" only appears once the target API accepts the credential. If validation fails, the card shows the status code and lets you re-enter credentials or retry.
  </Step>

  <Step title="Complete">
    The card collapses to a **{'<api name>'} connected** tile you can click through to the integration's settings page. The integration is now ready for functions.
  </Step>
</Steps>

The card is reload-safe. If you refresh or reopen the chat after credentials are already stored, the card resumes at validation instead of asking for the credential again.

#### Copilot continues on its own after you save credentials

You don't have to message Copilot after filling in the card. When Copilot surfaces a setup card, it pauses its turn and watches the card while you gather and paste the credential. A status line appears in the conversation while it waits. There's no countdown, because the wait is on you, and you can take up to 10 minutes before Copilot checks in.

Once you click **Save credentials**, the card runs its test call and Copilot resumes automatically with the result:

* **Test call succeeds.** Copilot carries on with the next step, such as generating a function on the integration.
* **Test call fails.** Copilot reports the failure reason, treats the connection as not working, and offers to reopen the card so you can re-enter the credential.
* **No test endpoint available.** Copilot tells you the credentials are stored but couldn't be verified, then continues. This isn't a failure.

If you haven't submitted anything when the wait expires, Copilot asks whether you still want to connect the integration instead of silently giving up. Use **Check now** on the status line to make Copilot re-check immediately instead of waiting for the next poll.

#### Replace credentials that failed the check

A stored credential isn't proof it works. When the test call fails, or an integration that shows as connected keeps failing auth, ask Copilot to reconnect it. Copilot reopens the setup card at the credentials stage so you can enter a replacement:

```text theme={"system"}
The Mosyle credential didn't work, let me re-enter it.
```

While the reopened card waits for the replacement, Copilot's status line reads "Waiting for the replacement credential" and the turn resumes on the new credential's test-call verdict, same as a first-time setup. Non-secret fields you already configured are pre-filled. Secret fields are always empty, because stored secrets never round-trip back into the card.

#### OAuth 2.0 integrations in chat

OAuth 2.0 integrations follow the same four stages, with a different credentials step:

1. **Ravenna extracts the OAuth config for you.** The grant type, authorization URL, token URL, and scopes are read from the API's catalog documentation on the server. You never type them into the card, and Copilot never guesses them. Copilot relays the resolved token URL and scopes in chat so you can check what your credentials will connect to.
2. **The card collects only a Client ID and Client Secret.** Enter the credentials from the OAuth app you registered with the provider, then click **Save credentials**. Both values go straight to Ravenna's encrypted vault. They never appear in the chat transcript and are never sent to the LLM. Saving creates an OAuth provider for your organization and attaches it to the integration, so there's no separate trip to **Settings → OAuth Providers**.
3. **The card connects the account.** After the credentials are saved, the card shows the same **Connect** popup used in Settings, because the provider's sign-in page can't be embedded in chat. Validation and publish then proceed as usual.

If the API's documentation doesn't state the authorization URL or token URL, the card adds a field for the missing one so you can paste it from the provider's OAuth guide. The authorization URL field only appears for the authorization code grant, since client credentials doesn't use one. **Save credentials** stays disabled until every missing URL is filled in.

If a relayed value looks wrong (a stale scope, the wrong token URL), tell Copilot the correction in chat. Copilot re-surfaces the card with the corrected config, and your correction wins over the extracted value.

#### Advanced auth integrations in chat

The setup card also handles the **Advanced** auth type, for APIs whose credentials don't fit a single field. The most common case is a login/token exchange: the API takes a username and password (or key pair) on its own login endpoint and returns a token to use on later requests, a pattern common among MDM-style APIs such as Mosyle. The card collects:

* **Login URL.** The endpoint credentials are posted to. Leave it blank if the API wants a fixed credential sent on every request instead of a login call.
* **Static header name and value.** One fixed header sent with requests. The value is a secret and goes straight to the vault.
* **Username field name, login username, and login password.** The field name matters: some APIs expect the login body's identifier key to be literally `email` rather than `username`, and a wrong name makes the login call fail. The password is a secret.
* **Where the token comes back.** A response header or a JSON body path, the header name or path, and the prefix (usually `Bearer`) to send it with afterward.

Copilot pre-fills the non-secret fields it read from the API's documentation (the login URL, field names, and token location) and tells you what belongs in each so you can confirm before saving. Secrets are never pre-filled and never pass through chat. Tokens obtained through the login call refresh on a fixed 24-hour schedule.

<Info>
  The card covers one static header plus one username/password pair. Anything past that (more fields, a credential in a query string or form body, a custom per-field prefix, a non-POST login call, or a different refresh window) is configured in the integration's settings page instead, in its **Configure** view.
</Info>

#### Reuse an already-registered OAuth provider

Before drafting a new integration, Copilot checks the OAuth apps already registered for your organization, including Ravenna-provided provider templates. A provider that shows a **Connect** tile in **Settings → Integrations** is registered even if nobody has connected an account yet. Copilot treats it that way instead of reporting that no integration exists.

When the app you ask for matches a registered provider, Copilot says so and creates the integration from that provider directly:

* The provider already carries a client ID, client secret, and auth endpoints. Copilot never asks you for credentials and skips the Credentials stage entirely.
* The connect step is the same one-click **Connect** popup used in Settings.
* Creating from a provider is idempotent. If an integration was already created from that provider, Copilot reuses it rather than making a duplicate.

To see what's available before you start, ask Copilot to list the registered providers:

```text theme={"system"}
What OAuth apps are already registered in this workspace?
```

<Info>
  Completing OAuth 2.0 setup in chat requires an **organization admin**, because saving the credentials creates an org-level OAuth provider. Non-admins can still ask Copilot to draft the integration, but an admin has to finish the connection.
</Info>

### Update an integration from Copilot chat

Copilot can also fix an existing custom API integration in place. If an integration has the wrong name, base URL, docs URL, or authentication type, ask Copilot to correct it. This works for any integration in the workspace, including a draft Copilot created earlier in the same conversation. Copilot updates the existing integration rather than creating a duplicate draft.

```text theme={"system"}
The Mailgun integration is pointing at the wrong base URL.
Change it to https://api.eu.mailgun.net
```

What happens next depends on which field changed:

* **Name or description.** The change applies immediately with no side effects. Docs validation status and stored credentials are untouched.
* **Base URL or default headers.** The change applies immediately and stored credentials are kept. If the integration was already connected, Ravenna flags it as **Needs reconnection** because the last connection test no longer reflects the current settings. See [Needs reconnection](#needs-reconnection).
* **Docs URL.** Foundry restarts docs research against the new URL, since the previous research was based on the old documentation. Wait for validation to finish before publishing the integration or generating functions on it.
* **Authentication type.** Ravenna clears the stored credentials, because the old and new auth types don't share a credential shape. Copilot then re-renders the **Credentials** setup card so you can enter the credential for the new type. No card appears if you switch to **No auth**. A connected integration is also flagged as **Needs reconnection** until the new setup passes a connection test.

Two authentication changes aren't available in chat:

* Copilot can't switch an existing integration **to** OAuth 2.0. OAuth setup happens when an integration is first created, through the inline setup card. If an existing integration should use OAuth instead, create a new integration.
* Copilot can't switch an integration that already has an OAuth provider linked **away from** OAuth 2.0. If you need a different auth mechanism for that API, create a separate integration.

***

## OAuth providers

Use these for tools where end users sign in with their own account, for example Google, Microsoft, or Salesforce. Each user who runs a function connects their account once, and the function executes as that account.

### Register a provider

<Steps>
  <Step title="Open Settings → OAuth Providers">
    Click **Add Provider**.
  </Step>

  <Step title="General">
    Give the provider a name, a slug (used internally), an optional description and logo, and the base URL and docs URL for the API.
  </Step>

  <Step title="OAuth">
    Enter the provider's authorization URL, token URL, scopes, client ID, and client secret. Expand **Advanced** if the provider has non-standard requirements (extra parameters, alternate credential delivery, or a non-`Bearer` API auth header). See [Advanced OAuth settings](#advanced-oauth-settings) below.
  </Step>

  <Step title="Research and save">
    Foundry researches the docs URL the same way it does for custom API integrations, then saves the provider. It's now enabled for the org and shows up in the **Custom** category of **Settings → Integrations**, where users can connect their accounts.
  </Step>
</Steps>

### Connect fields on Ravenna-provided providers

Some Ravenna-provided OAuth providers need a per-user value (a workspace subdomain, an account region, a per-tenant API host) to complete the OAuth flow. When you connect an account to one of those providers, Ravenna opens a **Connect {'{provider name}'}** dialog and asks for the required values before starting sign-in. Each field shows a label, an optional placeholder, and one-line help text explaining where to find the value.

The **Connect** button stays disabled until every required field has a value. Ravenna then URL-encodes each value, substitutes it into the provider's URLs, and starts the OAuth flow. It stores the values alongside the connection and reuses them on every API call from that user's functions.

<Info>
  Connect fields only appear when a provider template defines them, and most providers don't. Custom OAuth providers you register from **Settings → OAuth Providers** don't use connect fields.
</Info>

You can disable or delete providers at any time from **Settings → OAuth Providers**.

### Advanced OAuth settings

Most providers work with just the basic fields above. Expand **Advanced** on the OAuth tab when a provider deviates from the OAuth 2.0 defaults. Foundry auto-expands the section when you edit a provider that already has non-default values.

| Field | When to use it | Default |
| - | - | - |
| **Grant type** | Which OAuth 2.0 flow Foundry uses to obtain tokens. Keep **Authorization Code** when each user signs in with their own account. Switch to **Client Credentials** for a server-to-server provider that uses a single shared machine credential for the whole org. See [Grant types](#grant-types) below. | Authorization Code |
| **Auth URL params (JSON)** | Extra query parameters appended to the authorization URL. Google needs `{"access_type": "offline", "prompt": "consent"}` to issue refresh tokens. | None |
| **Token exchange params (JSON)** | Extra parameters merged into the token request body. Use for provider-specific fields the OAuth 2.0 spec doesn't define. | None |
| **Credential delivery** | How the client ID and secret are sent to the token endpoint. **Authorization Header** uses HTTP Basic auth (most providers). Switch to **Request Body** if the provider expects `client_id` and `client_secret` in the form body instead. | Authorization Header |
| **Token exchange format** | Content-Type of the token request body. **Form URL-encoded** is the OAuth 2.0 default. Switch to **JSON** for providers that require it. | Form URL-encoded |
| **API auth header scheme** | The scheme prefix Foundry uses in the `Authorization` header when calling the provider API with the access token. Set this when a provider rejects the standard `Bearer` prefix. Discord bot tokens, for example, use `Bot`. | `Bearer` |

<Info>
  The API auth header scheme only changes the prefix Foundry sends with API calls (for example `Authorization: Bot <token>` instead of `Authorization: Bearer <token>`). It doesn't change how the token itself is obtained.
</Info>

### Grant types

Foundry supports two OAuth 2.0 grant types. Pick the one that matches how the third-party API expects to be called.

**Authorization Code** is the default and the right choice for any provider where each user should act as themselves, such as Google, Microsoft, Salesforce, GitHub, and most consumer APIs. Each user connects their own account from **Settings → Integrations**, and Foundry runs functions as the connected user. Tokens refresh automatically using the stored refresh token.

**Client Credentials** is a server-to-server flow with no user redirect. Foundry exchanges the client ID and client secret directly for an access token, and every function call uses that same machine credential. Pick it when the provider issues an org-level token rather than per-user tokens, for example an internal API that authenticates the whole organization with a single service account.

When you choose Client Credentials, the **Authorization URL** field is no longer required. The connect step doesn't open a sign-in page either: clicking **Connect** in **Settings → Integrations** fetches a token immediately and reuses it for every user in the connecting workspace. Tokens are re-fetched in place when they expire, since there's no refresh token.

<Info>
  Client Credentials is only offered for organization-owned OAuth providers, since the credential is shared across everyone in the org. Built-in Ravenna providers stay on Authorization Code.
</Info>

### Connect an account

Once a provider is registered, each user connects their own account by going to **Settings → Integrations**, finding the provider in the **Custom** category, and clicking through the standard OAuth sign-in flow. Tokens refresh automatically.

For Client Credentials providers, the connect step is a single click rather than a sign-in flow, and any user in the workspace who runs a function on the integration uses the same shared token. Client Credentials connections must be made from inside a workspace.

### Workspace ownership of OAuth connections

A Foundry OAuth connection made from **Settings → Integrations** belongs to the workspace that connected it. This applies to both Ravenna-provided providers and org-registered providers, whichever grant type they use.

* Only the connecting workspace can see and use the connection, unless an organization admin shares it through [Workspace Access](#share-an-integration-with-other-workspaces).
* Only actions in a workspace with access can use the connection. Other workspaces can't attach it to their actions.
* The OAuth provider itself stays registered at the organization level. Workspace ownership only applies to the connection made from it.

Each provider supports one connection per organization for now. If a second workspace tries to connect a provider that another workspace already connected, Ravenna blocks the connection. The error names the workspace that owns the connection, for example:

```text theme={"system"}
Google Calendar is connected in the IT workspace.
```

To use that connection from your workspace, ask an organization admin to add your workspace to the connection's **Workspace Access** list. See [Share an integration with other workspaces](#share-an-integration-with-other-workspaces).

### Share an integration with other workspaces

Organization admins can share a workspace-owned Foundry integration with other workspaces in the organization. Use this when more than one workspace needs the same OAuth connection or custom integration, instead of connecting it again. Sharing applies to both Foundry OAuth provider connections and custom API integrations.

To share an integration:

1. Go to **Settings → Integrations** and click the integration's tile. For a custom integration, the tile opens its connections view.
2. On the connection row, open the **⋯** menu and choose **Workspace Access**.
3. Select the workspaces that should have access, then save.

The workspace that created the integration always keeps access. Each connection row shows a badge with who can use it: the workspace name when one workspace has access, a count such as **3 workspaces**, or **All workspaces** when every workspace can use it.

<Warning>
  Sharing is one-way. Once you save a Workspace Access list for a private integration, it stops being private to the workspace that created it. You can still change which workspaces have access later, but you can't make it private to its original workspace again.
</Warning>

Workspaces that aren't on the access list see a **Restricted** badge on the connection. In those workspaces, the connection's **⋯** menu only offers **Workspace Access**, so an organization admin can add the workspace from there.

### Default headers on OAuth integrations

Some APIs require a static header on every request in addition to the OAuth access token. Adobe APIs, for example, expect an `x-api-key` header alongside `Authorization: Bearer <token>`. Add these as **Default Headers** on the Foundry OAuth integration:

<Steps>
  <Step title="Open the integration in Foundry">
    In the Foundry studio, select the integration in the left sidebar and click **Edit**.
  </Step>

  <Step title="Add the headers">
    On the **Authentication** tab, add each header under **Default Headers**. A value can be plain text or a vault credential. Pick a credential for secret values such as an API key.
  </Step>

  <Step title="Test the connection">
    Click **Test Connection** to send an authenticated request with the OAuth token and your default headers. Test Connection only appears after an account is connected, because there's no token to test with before then.
  </Step>
</Steps>

Foundry sends the default headers with every request the integration makes, alongside the OAuth bearer token:

```http theme={"system"}
GET /v1/assets HTTP/1.1
Authorization: Bearer <access token>
x-api-key: <your Adobe client ID>
```

<Info>
  The Default Headers editor for OAuth integrations is only on the Foundry studio's **Authentication** tab. It isn't available from the provider tiles in **Settings → Integrations** yet.
</Info>

### Reconnect a Foundry OAuth account

A refresh token can eventually expire. Okta's default refresh token lifetime is a common example, and some providers also invalidate refresh tokens after long inactivity or a password change. When that happens, functions built on the integration start failing with auth errors even though the connection still exists.

Use **Reconnect** to renew credentials in place. Reconnect re-runs the OAuth consent flow against the same connection, so the new tokens replace the old ones while everything else on the integration (its configured actions, its integration settings, and the automatic token-refresh schedule) is preserved. There's no need to disconnect first, and you don't have to re-link the integration to any functions that already use it.

Reconnect is available in two places:

* **In the Foundry builder.** Open the function, go to the **Authentication** tab, and click **Reconnect** next to the connected account.
* **In the integration tile.** From **Settings → Integrations**, open the integration, and choose **Reconnect** from the actions menu on the connection row.

Both entry points run the same in-place update: Ravenna reuses the connection's stored connect field values, sends you through the provider's consent screen, and writes the fresh tokens back to the existing connection.

<Info>
  Reconnect is the recommended remedy when a refresh token expires (for example on an Okta connection). Disconnecting and reconnecting also works, but it drops the connection and requires re-linking any functions that reference it. Reconnect avoids that.
</Info>

<Info>
  Client Credentials providers don't show a **Reconnect** button in the integration tile's manage dialog. They don't require a user redirect, so tokens are re-fetched in place automatically when they expire. There's nothing to re-consent to.
</Info>

<Callout icon="book-open" color="#7C3AED">
  Need help registering a provider? The Foundry guide has end-to-end walkthroughs for [Google Cloud](/guides/how-to/foundry/setup-oauth/google-cloud), [GitHub](/guides/how-to/foundry/setup-oauth/github), and [DocuSign](/guides/how-to/foundry/setup-oauth/docusign), plus a [shared overview](/guides/how-to/foundry/setup-oauth/overview) you can adapt to any provider.
</Callout>

***

## Native credential bridges

Some integrations you have already connected to Ravenna can share their credentials with Foundry actions directly. When a native bridge is available, you do not need to configure a separate Foundry integration. The action runs with the same OAuth token your Ravenna integration uses.

**Available native bridges:**

| Integration | What Foundry can access |
| - | - |
| Notion | Read and write pages, databases, and blocks in connected Notion workspaces. |
| Jamf Pro | Query and manage devices, users, and policies in your Jamf Pro instance. |
| Slack | Post messages, read channels, and interact with the Slack API using your connected bot token. |
| Google Workspace | Access Google Drive, Calendar, and Admin APIs through your connected service account. |
| Okta | Read and manage users, groups, and applications in your Okta org. |
| Microsoft Entra | Read and manage users, groups, and applications in your Entra tenant. |
| Cloudflare Access | Read and manage Access applications, policies, and identity providers on your Cloudflare account. |
| FleetDM | Query device inventory and run live queries against enrolled hosts. |
| Jira | Read and write issues, projects, and comments in your connected Jira site. |
| Linear | Read and write issues, projects, and comments in your Linear workspace. |
| GitHub | Read and write issues, pull requests, and repository contents on your connected GitHub account. |
| PagerDuty | Read and manage incidents, services, and schedules in your PagerDuty account. |
| HubSpot | Read and write CRM records (contacts, companies, deals, tickets) via the HubSpot API. |
| Incident.io | Read and manage incidents, follow-ups, and workflows via the Incident.io API. |
| Vanta | Read compliance data (controls, tests, and evidence) in your Vanta account. |
| Freshservice | Read and write tickets, requesters, assets, and changes in your Freshservice instance; per-tenant subdomain. |
| JumpCloud | Read and manage users, systems, applications, and policies in your JumpCloud org. |
| Microsoft Intune | Read and manage devices, users, and policies via the Microsoft Graph endpoints Intune exposes. |
| Iru | Per-tenant device and identity data through your Iru workspace. |
| Rippling | Read and manage employees, groups, and app assignments via the Rippling REST API. |

**Using a native bridge:**

When you create or generate a Foundry action, select the connected integration from the integration picker. Foundry injects the integration's credentials into the sandbox at runtime. Your action code can call the third-party API directly without managing authentication.

<Info>
  Native bridges use the same permissions your Ravenna integration has. If your Notion integration has read-only access, Foundry actions using that bridge also have read-only access.
</Info>

***

## Managing integrations

* **Edit** to update sign-in details, the base URL, or the docs URL.
* **Re-research** to make Foundry re-read the documentation if the API has changed.
* **Delete** to remove the integration. Remove or unpublish any functions using it first.

### Needs reconnection

When you change a connected integration's base URL, auth type, default headers, auth settings, or OAuth provider, Ravenna flags it as **Needs reconnection**. The previous connection test was run against the old settings, so Ravenna no longer treats it as proof that the integration works. Saving the form without changing any of these fields doesn't set the flag.

The flag appears in three places:

* A **Needs reconnection** badge next to the integration in the Foundry sidebar.
* The Copilot setup card, which reads **{'<api name>'} needs reconnection** instead of **connected**. Click the card to open the integration and re-test.
* The integration's status badge in **Settings → Integrations**.

To clear the flag, open the integration and run **Test connection** on the **Authentication** tab. A successful test marks the integration as connected again. The integration stays usable while it's flagged, so functions built on it keep running in the meantime.

<Info>
  Draft integrations are never flagged, because they don't have a connected state yet.
</Info>

<Callout icon="link" color="#6B7280">
  Ready to build? Learn how to [create a function](/documentation/automate/foundry/actions).
</Callout>


## Related topics

- [List Foundry integrations](/api/foundry/list-foundry-integrations.md)
- [Create a Foundry integration](/api/foundry/create-a-foundry-integration.md)
- [Delete a Foundry integration](/api/foundry/delete-a-foundry-integration.md)
- [Get a Foundry integration](/api/foundry/get-a-foundry-integration.md)
- [Update a Foundry integration](/api/foundry/update-a-foundry-integration.md)


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