# Connect your own API

Texa calls your HTTP API directly. Import an OpenAPI file or a documentation page, choose how Texa signs in, and map the answer.


If your system has an HTTP API, Texa can call it for Texa AI with no code on your side. Your
credentials are stored encrypted and never shown again; Texa AI never sees them.

## 1. Add the connector

In Texa Desk, **Texa AI → Actions → Connectors → Your own system**, choose **Texa calls your API**
and give its base address (`https://api.yourcompany.com`). Then pick how Texa signs in:

| Sign-in | Sends |
|---|---|
| API key | a header (`X-Api-Key: …`) or a query value you name |
| Bearer token | `Authorization: Bearer …` |
| Basic | `Authorization: Basic …` from a username and password |
| OAuth 2 client credentials | gets a token from your token URL, keeps it until it expires and refreshes it before |
| HMAC signing | a signature header over the body (or `timestamp.body`), SHA-256, hex or base64 |
| The signed-in customer's own token | the customer's token from your website or app, in the header you name, on that customer's actions only ([how](/guides/website-and-app#3-acting-as-the-customer)) |

## 2. Make the actions

- **Import an OpenAPI 3 file:** every operation becomes a draft action.
- **No OpenAPI file?** Give the address of your API's documentation page. Texa AI drafts the
  actions from it.
- **Or write one by hand.**

Nothing is saved until you review each draft: its description, inputs, outputs, which outputs are
private, whether it changes something, and whether the customer must be verified first.

## 3. The request and the answer

Under the hood, an action is a request template and a mapping of the answer. You can edit both:

```yaml
request:
  method: GET
  path: "/transfers/{{ inputs.reference | urlencode }}"
response:
  success_when: {path: "$.status", equals: true}
  error: {path: "$.message"}
  outputs:
    status: {path: "$.data.status", map: {success: paid_out, pending: processing, "*": failed}}
    amount: {path: "$.data.amount", divide: 100}
    sent_at: {path: "$.data.created_at", date: true}
```

- **Placeholders:** `{{ inputs.name }}`, `{{ secrets.api_key }}`, `{{ idempotency_key }}`, with
  filters `urlencode`, `kobo` (naira to kobo), `upper`, `lower`, `digits`, `int`, `str`, `json`,
  `hexkey` (a 40-character key for APIs that take letters and digits only). In a JSON body, a
  value that is only a placeholder keeps its type. A missing value is an error that names it,
  never an empty value sent by accident.
- **Paths** are a small, safe part of JSONPath: `$`, `.key`, `[n]`, `[*]`. No expressions, no scripts.
- **A read's HTTP 404** means "no such record" (Texa AI asks the customer to check), not a failure.
- **Writes carry `idempotency_key`:** pass it to your API so a retry doesn't do it twice.

## Where Texa will and won't call

- Only the hosts the connector is set up for: its base address, plus any you list.
- `https` for live connectors.
- **Never a private address** (`10.x`, `192.168.x`, `localhost`, cloud metadata), however the name
  resolves, checked again at connect time. Redirects are not followed.

To reach systems inside your network, use [your own server](/guides/action-server) or the
[Texa Relay](/guides/relay).
