# Connections in Headless

A headless integration declares its [connections](https://prismatic.io/docs/integrations/connections.md) in its configuration, instead of on a config page. Your `init` function, server functions, and flows can then use them, and your app lets customers choose or create them.

## Declare connections[​](#declare-connections "Direct link to Declare connections")

Add connections to the `connections` property of a configuration scope. Each key names the connection within your integration:

src/configuration.ts

```typescript
import {
  configuration,
  customerActivatedConnection,
} from "@prismatic-io/spectral";
import { z } from "zod";

export const integrationConfiguration = configuration({
  instance: {
    schema: z.object({
      channel: z.object({ id: z.string(), name: z.string() }),
    }),
    version: "slack-alerts-v1",
    connections: {
      slack: customerActivatedConnection({ stableKey: "slack-oauth" }),
    },
  },
});

```

The `instance` scope accepts these kinds of connections:

| Function                                         | Connection type                                                                                                                                                          |
| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `customerActivatedConnection({ stableKey })`     | A [customer-activated connection](https://prismatic.io/docs/integrations/connections/integration-agnostic-connections/customer-activated.md) your customer creates.      |
| `organizationActivatedConnection({ stableKey })` | An [org-activated connection](https://prismatic.io/docs/integrations/connections/integration-agnostic-connections/org-activated-customer.md) your organization supplies. |
| `connectionConfigVar({ ... })`                   | An [integration-specific connection](https://prismatic.io/docs/integrations/connections/integration-specific.md) with its own inputs.                                    |

The `userLevel` scope accepts `userActivatedConnection({ stableKey })` for a [user-level connection](https://prismatic.io/docs/integrations/connections/integration-agnostic-connections/user.md), or `connectionConfigVar()`.

## Use connections in init and server functions[​](#use-connections-in-init-and-server-functions "Direct link to Use connections in init and server functions")

`init` and server functions receive only the connections they declare. List them with their scope, such as `instance.slack`, and read them from `context.connections`:

src/configuration.ts

```typescript
import { serverFunction, util } from "@prismatic-io/spectral";

export const listChannels = serverFunction({
  label: "List channels",
  inputSchema: z.object({ search: z.string().optional() }),
  outputSchema: z.array(z.object({ id: z.string(), name: z.string() })),
  connections: ["instance.slack"],
  perform: async (context, { search }) => {
    const token = util.types.toString(
      context.connections.instance.slack.token?.access_token,
    );
    return searchSlackChannels(token, search);
  },
});

```

`init` declares connections the same way, in `init.connections`. Spectral checks the declared keys against your configuration at compile time, so a typo in a connection key is a type error.

## Use connections in flows[​](#use-connections-in-flows "Direct link to Use connections in flows")

Flows read the instance's connections from `context.connections`, by scope:

src/flows.ts

```typescript
onExecution: async (context) => {
  const slack = context.connections?.instance?.slack;
  // ...
},

```

## Let customers choose connections in your app[​](#let-customers-choose-connections-in-your-app "Direct link to Let customers choose connections in your app")

When your app loads a configuration with Solis, the configuration lists the connections that `init` and each server function need. Each requirement offers the customer's existing connections that can fill it. Your organization supplies org-activated connections, so they're never offered to customers.

Your app keeps the customer's choices as a list of `{ key, id }` selections, using each requirement's `key` exactly as the SDK gives it, and passes them when it calls `init` or a server function:

```tsx
// A requirement from configuration.data.connections, and the option the customer chose
const [requirement] = configuration.data.connections.data.init;
await configuration.actions.init.execute({
  connections: [{ key: requirement.key, id: selectedConnectionId }],
});

```

A requirement backed by a customer-activated connection can also create a new connection in one click. For OAuth 2.0 connections, this opens the provider's consent screen.

See [Building configuration UIs with Solis React](https://prismatic.io/docs/embed/headless/react.md#connections) for the details.
