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

# Authentication

> Secure action calls — store org-wide secrets as global variables, pass per-user tokens from the widget, and rely on context headers OpenCX attaches automatically.

Your action endpoint decides who's allowed to call it. OpenCX gives you three ways to reach that decision — pick one or combine them.

## The Three Paths

| Path                 | Use it for                                                                       | Where it lives                                            |
| -------------------- | -------------------------------------------------------------------------------- | --------------------------------------------------------- |
| **Global variables** | Credentials every customer shares — a server-to-server API key, a signing secret | [Settings → Variables](https://platform.open.cx/settings) |
| **Widget headers**   | Credentials that differ per customer — a session token, a per-user JWT           | Your frontend, passed to the widget at init               |
| **Context headers**  | Identifying the OpenCX-side session / org / contact to your API                  | Attached automatically by OpenCX                          |

## Global Variables

Store once, OpenCX injects the value into every action call for your organization. Values are **encrypted at rest** and **decrypted per request**.

<Steps>
  <Step title="Open the variables page">
    Go to **[Settings → Variables](https://platform.open.cx/settings)**.
  </Step>

  <Step title="Add a variable">
    Set a **key** and **value**. The key becomes the HTTP header name on every outbound action call.
  </Step>

  <Step title="Reference from an action">
    Nothing further to wire up — any action whose endpoint sits behind that header will authenticate.
  </Step>
</Steps>

<Note>
  Use a full `Authorization` header value (e.g. `Bearer <token>`) when your API expects Bearer auth — OpenCX sends the value verbatim, it does not prepend `Bearer `.
</Note>

## Widget Headers

Pass per-user credentials from your frontend at widget-init time. OpenCX uses them only for that contact's action calls and does not persist them.

```javascript theme={"dark"}
const options = {
  token: 'YOUR_COPILOT_TOKEN',
  headers: {
    Authorization: `Bearer ${userJwt}`,
  },
};
```

Widget headers **override** same-named global variables for that contact's session. Use this when each signed-in customer needs their own scoped token.

## Context Headers

When your org has context headers enabled, OpenCX adds four identifying headers to every action call:

| Header                      | Value                                              |
| --------------------------- | -------------------------------------------------- |
| `x-opencx-org-id`           | Your organization UUID                             |
| `x-opencx-session-id`       | The conversation session UUID — the trace key      |
| `x-opencx-ticket-number`    | Numeric ticket ID for the session                  |
| `x-opencx-external-user-id` | The contact's external ID if they're authenticated |

Your API can use these to:

* **Trace** an action call back to a specific conversation in the [OpenCX inbox](https://platform.open.cx/inbox) — the session ID is a clickable link.
* **Rate-limit** per org without customers passing their own org ID as a parameter.
* **Scope** responses — e.g. return a contact's orders based on `x-opencx-external-user-id` instead of trusting a query parameter the AI extracted.

<Note>
  Context headers are opt-in at the org level. If you need them on, ask support to enable automatic action headers for your org.
</Note>

Every action call also carries `User-Agent: OpenCX` so your firewall and logs can filter.

## Choosing A Path

| Situation                                                                 | Path                                                                             |
| ------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| Every customer hits the same backend with the same server-to-server key   | **Global variable**                                                              |
| Each signed-in customer has their own scoped token                        | **Widget header** (with a global variable for any shared service-account header) |
| Your API needs to know which OpenCX session / org / contact made the call | **Context headers**                                                              |

## Security Best Practices

<AccordionGroup>
  <Accordion title="Validate context headers server-side" icon="lock-keyhole">
    Treat `x-opencx-org-id` as a signal, not a credential — pair it with a global-variable shared secret your API also checks. That way a leaked URL alone can't forge OpenCX traffic.
  </Accordion>

  <Accordion title="Don't log full header values" icon="eye-slash">
    Redact anything matching `Authorization`, `*-Token`, `*-Key` in your access logs. OpenCX does not replay headers, but your own log pipeline and dashboards can.
  </Accordion>

  <Accordion title="HTTPS only" icon="shield-check">
    OpenCX refuses to call `http://` URLs. If your endpoint isn't behind TLS today, put it behind a gateway that is.
  </Accordion>

  <Accordion title="Rotate secrets without losing conversations" icon="arrows-rotate">
    Update the global variable value — no action edit needed. Existing in-flight tool calls finish against the old value; the next call uses the new one.
  </Accordion>
</AccordionGroup>

***

## Related Documentation

<CardGroup cols={2}>
  <Card title="Build An Action" icon="plug" href="/actions/build-an-action">
    Form fields, headers, parameters, test.
  </Card>

  <Card title="Execution" icon="diagram-project" href="/actions/execution">
    How headers reach your API at call time.
  </Card>

  <Card title="Troubleshooting" icon="wrench" href="/actions/troubleshooting">
    401s, 403s, and signal-header gotchas.
  </Card>

  <Card title="Widget Authentication" icon="user-lock" href="/widget/authentication">
    Full widget auth model including identity verification.
  </Card>
</CardGroup>
