Custom API connectors
Connect an API that is not in the directory with the Generic REST / OpenAPI connector, and expose your own API to agents.
Updated 8 Oct 2026
On this page
When to use a custom connector
Use the Generic REST / OpenAPI connector (generic-rest-openapi) for an internal API, a partner API or any provider outside the connector directory. You describe the operations; Nexra runs them with the same safety controls as built-in connectors.
Set up in the console
Open Dashboard → Connect → Custom → Connect your own API.
Choose the project, a name and the business area.
Enter the API base address. It must be HTTPS, with no user name, password, query string or fragment. Use the sandbox or test address: the builder always creates a sandbox connection.
Choose the authentication and enter the credential (see the table below). The credential goes straight to the managed workspace vault; the connection only stores a reference to it.
Add operations, by hand or with Import from OpenAPI (below). Each operation has:
- a record name and action, which form its key, for example orders.list. Actions are list, get, search, create, update and upsert. Delete is not available.
- an HTTP method allowed for that action, and a path such as /orders/{orderNumber}.
- where records appear in the response, for example data.items (reads only).
- typed fields: string, number, boolean, date, object or array, each optionally required.
- optional query inputs. Path values such as {orderNumber} are always required inputs.
- an optional identifier field used to match records and fill a single path value.
- pagination for list and search: none, cursor, page number or offset and limit.
- for writes, an optional idempotency header such as Idempotency-Key.
Review write consent. Every write operation is off by default. Tick only the writes the API owner has approved, then confirm the consent statement.
Save, then run Test read.
Test read
Test read calls the first page of your list operation once. It shows the number of records returned and their field names. It never shows or stores record values, and it never sends a write.
Import from OpenAPI
Paste or upload an OpenAPI 3.0 or 3.1 document in JSON or YAML. Nexra reads it without calling the API and lists the operations it can use. Reads are selected for you; writes are left for you to choose. After you add them, you can review and edit each operation before saving.
The first HTTPS server becomes the suggested base address.
A bearer, basic, header API key or OAuth client-credentials scheme becomes the suggested authentication.
Operations that cannot run safely are listed under Not imported with the reason. This covers DELETE operations, multipart or file uploads, form-encoded bodies and file downloads such as PDF or CSV.
Query parameters that are lists or objects, cookies and extra headers are noted and left out.
Very large documents may exceed the request size limit. If that happens, trim the document to the paths you need.
Authentication
| Method | You enter | Sent as |
|---|---|---|
| Bearer token | Token | Authorization: Bearer … |
| API key in a request header | Header name and key | The named header |
| Basic | Username and password | Authorization: Basic … |
| OAuth 2.0 client credentials | Token URL, scope, client ID and secret | A bearer token from the token URL, cached until shortly before it expires |
| None | Nothing | Nothing |
API keys in the query string are not supported for new connectors, because addresses end up in logs. Ask the API owner to accept the key in a header. Connectors created before this change keep working.
How writes are governed
A write that is not enabled on the connection is shown as unavailable and cannot be published in a flow. The runtime also refuses it before any request is sent.
To enable a write later, edit the connection. The connection then returns to draft and must be tested again. The change is recorded in the audit log.
Enabled writes still run only in a reviewed flow. Production needs a production connection prepared from the tested sandbox connection, plus an approved deployment.
A write without an idempotency header is not retried automatically. Check the destination before you retry it by hand.
Production uses the same base address as the sandbox connection it was prepared from. A separate production address is not supported yet.
Full configuration over the API
POST /api/console/connect/connections with connectorKey: "generic-rest-openapi". New connections are validated as definition version 2. For the OpenAPI import, call POST /api/console/connect/custom-api/openapi-import with { "document": "<JSON or YAML text>" }; it returns candidate operations and the skipped list, and saves nothing.
{
"connectorKey": "generic-rest-openapi",
"projectId": "<project-id>",
"name": "Order management",
"environment": "sandbox",
"configuration": {
"baseUrl": "https://oms.example.com/api/v1",
"secretReference": "<secretReference from POST /api/console/connect/credential-references>",
"authentication": {
"type": "oauth2_client_credentials",
"tokenUrl": "https://auth.example.com/oauth/token",
"scope": "orders.read orders.write"
},
"operations": {
"orders.list": {
"method": "GET",
"path": "/orders",
"responseRecordsPath": "data",
"inputs": [{ "name": "status", "in": "query", "type": "string" }],
"fields": [
{ "name": "orderNumber", "type": "string", "required": true },
{ "name": "total", "type": "number" },
{ "name": "placedAt", "type": "date" }
],
"identifierField": "orderNumber",
"pagination": {
"mode": "page",
"pageParam": "page",
"pageSizeParam": "per_page",
"pageSize": 100
}
},
"orders.update": {
"method": "PATCH",
"path": "/orders/{orderNumber}",
"identifierField": "orderNumber",
"idempotencyHeader": "Idempotency-Key",
"fields": [
{ "name": "orderNumber", "type": "string", "required": true },
{ "name": "status", "type": "string" }
]
}
},
"allowedWriteOperations": ["orders.update"]
}
}Operation fields
| Field | Purpose |
|---|---|
| Operation key | <entity>.<action>; action is list, get, search, create, update or upsert |
method | list and get: GET; search: GET or POST; create: POST; update and upsert: PUT, PATCH or POST. DELETE is refused. |
path | Starts with /, no query string. {name} values come from pathParameters, the input or the mapped record. |
inputs | Declared path and query inputs with a type. Required query inputs are checked before the request. |
fields | Typed record fields. Reads are converted where safe; writes send only these fields and reject missing required ones. |
identifierField | Business identifier, copied to id on read records that have none |
responseRecordsPath | Where the records sit in the response |
pagination | mode cursor (cursorInputName, nextCursorPath), page (pageParam, pageSizeParam, pageSize) or offset (offsetParam, limitParam, limit) |
idempotencyHeader | Header that receives Nexra's idempotency key on writes |
allowedWriteOperations | Write operation keys that are enabled. Empty by default. |
A POST search is a read. Every other non-GET operation is a write.
Inputs at run time
Operations receive pathParameters, query (string, number or boolean values) and cursor, plus the record to write. Every call carries X-Correlation-Id. Errors are classified as for built-in connectors: 401 is authentication, 403 permission, 404 not found, 429 rate limit (with Retry-After honoured), other 4xx validation and 5xx provider. A write that is not enabled fails with write_operation_not_enabled.
Network reach
The connector calls public HTTPS addresses only. An internal system must be reachable through a public HTTPS endpoint, such as an API gateway that allows Nexra's outbound addresses.
Expose your own API to agents
To let AI agents call your API rather than move data with it, import its OpenAPI document into an MCP server instead. See Use the Nexra MCP server.