2. Connect a system
A system is anything with an API. You connect it by its address. Inferrex asks for nothing else up front.
The rule to remember: nothing is saved until a live signed-in read passes. The test must read real data from the system before the system exists in your workspace, and the system cannot be approved until that read is proven.
In the app
Open Systems and add a system. The wizard has five steps:
- Address. Give the address the system's API lives at, such as
https://api.example.com/v2. If part of it differs for each account, put that part in braces, such ashttps://{region}.example.com. - Sign-in. Choose how the API expects Inferrex to sign in. Inferrex asks the API and shows what it found. What you choose is used.
- Credentials. Type the credentials, or sign in in the cloud shell if the system uses a command-line sign-in. Credentials are stored encrypted, for this environment only, and only once the test passes and you save.
- Test. Inferrex signs in with what you typed and reads one endpoint. It must answer with data. If Inferrex cannot find data at the address, add a path that returns records, such as
/customers. - Name. Give the system the name people in your team use for it, then save. Saving starts the first read.
When the first read finishes, the system waits for your review (chapter 3).
From the API
The same five steps are four calls.
Step 1: ask the API how it signs in
curl -X POST https://api.inferrex.com/v1/connections/detect-auth \
-H "X-API-Key: $INFERREX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"endpoint": "https://api.example.com/v2"}'
Response shape:
{
endpoint: string;
authType: string; // api-key, bearer, basic, oauth2, or unknown
credentialFields: string[]; // the credential fields to fill in
confidence: number;
fieldValues: { headerName?: string; tokenUrl?: string; scopes?: string[] };
probe: { outcome: string; status: number; authType: string | null; credentialFields: string[] } | null;
addressCorrection: string | null;
signInWithProvider: { provider: string; providerKey: string } | null;
}
Read it like this:
authType: "unknown"means the API did not say. It does not mean the API is open. Choose the method yourself.probe.outcome: "open"means that one address answered without asking for a credential. The API's own endpoints may still need one.addressCorrectionis set when the address you gave is a website or documentation page and not the API. Use the corrected address.signInWithProvideris set when the provider offers its own sign-in page for this address. See "Sign in with the provider" below.- Use
credentialFieldsas the keys of thecredentialsobject in the next calls.
Step 2: test the address and sign-in
curl -X POST https://api.inferrex.com/v1/connections/test \
-H "X-API-Key: $INFERREX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://api.example.com/v2",
"authType": "bearer",
"credentialRef": "orders-api-token",
"readPaths": ["/customers"]
}'
authType is one of oauth2, api-key, basic, bearer, aws-sigv4, jwt, mtls, custom, none, service-account.
Send the sign-in in one of two ways:
credentialRef: the name of a secret already saved in this workspace (Workspace settings, Secrets). Prefer this. The value never leaves the vault.credentials: the credential values. The test uses them once and stores nothing.
The test stores nothing: no system, no secret, no job. Response shape:
{
outcome: string;
httpStatus: number | null;
testedUrlTemplate: string; // placeholders shown as {name}, never their values
detail: string; // what the result means, in plain words
durationMs: number;
provedBy: string | null; // the endpoint whose answer proved the read
endpointSource: string;
}
Only two outcomes pass:
outcome |
Meaning |
|---|---|
signed-in |
A signed-in request to a read endpoint answered 2xx with data. provedBy names the endpoint. |
read-without-sign-in |
The same, for an API that takes no sign-in. |
Everything else is a fail, and detail says what to change:
outcome |
Meaning |
|---|---|
credentials-rejected |
The API refused the sign-in details (401), or the token address refused the client id and secret. |
forbidden |
The API refused this request (403). The sign-in may be right but not allowed here. |
organisation-not-selected |
The sign-in names no organisation and the provider requires one. Sign in with the provider again and choose one. |
not-found |
Nothing at this address (404). |
not-a-read |
A 2xx, but an HTML page, an empty body or an error message, not data. |
api-error |
Any other status. |
unverified |
No read endpoint is known, so only the base address could be tried. Add readPaths. |
unreachable |
No answer. |
redirect |
The API answered with a redirect. Redirects are not followed. |
not-testable |
This sign-in cannot be tested with one request, or a value it needs is not set. |
Step 3: connect
curl -X POST https://api.inferrex.com/v1/connections/infer \
-H "X-API-Key: $INFERREX_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: connect-orders-api-001" \
-d '{
"url": "https://api.example.com/v2",
"authType": "bearer",
"credentialRef": "orders-api-token",
"displayName": "Our order system",
"readPaths": ["/customers"]
}'
The server runs the test again first. If it does not pass, nothing is stored and the error carries the test result in details.test.
Useful optional fields:
| Field | Use |
|---|---|
displayName, description, tags |
What your team calls the system and how you group it. |
specUrl |
A public https link to the API's own description (OpenAPI or Swagger). |
readPaths |
Paths that return records, each starting with /, for an API that publishes no description. |
pathParams |
A value for each {placeholder} in the address or paths. Give {"secretRef": "<name>"} to take the value from a saved secret. |
existingMcpServer |
The address of the system's own MCP server, on a public https host. |
cliSessionId, cliBinary |
For a system reached through a command-line tool in a cloud shell session (chapter 10). |
The response is 202 with { connectionId, jobId, estimatedTimeSeconds }. The first read takes a minute or two.
Step 4: wait for the first read
curl https://api.inferrex.com/v1/connections/CONNECTION_ID/status \
-H "X-API-Key: $INFERREX_API_KEY"
Response shape: { connectionId, status, createdAt, manifestId, manifestStatus, manifestVersion, overallConfidence }.
While status is inferring, Inferrex is still reading the API: call again. When it is awaiting-review, the read has finished: review it, then approve (chapter 3). After approval it is approved.
The full set of states a system can be in is inferring, awaiting-review, approved, active, error, suspended and archived.
You can also follow the jobId with GET /v1/jobs/:id.
Sign in with the provider
Some providers offer their own sign-in page. When they do, detect-auth returns signInWithProvider, and the app's wizard offers Sign in with the provider on the sign-in step.
This needs a person in a browser. From code, POST /v1/oauth/initiate returns { authorizeUrl, state }: send the person to authorizeUrl. When they approve, the provider sends them back to Inferrex, which saves the tokens on the connection.
If the sign-in covers several organisations, you choose which to connect:
GET /v1/connections/:id/oauth-organisations/:picklists them while the choice is open.POST /v1/connections/:id/oauth-organisations/:pickwith{ "organisationIds": [...] }connects them.
Each organisation becomes its own system with its own id. Inferrex never picks one for you.
Look after a connected system
| To do this | Call | MCP tool |
|---|---|---|
| List systems | GET /v1/connections |
connection_list |
| Test the saved sign-in again | POST /v1/connections/:id/test |
connections_test_saved_connection |
| Rename, describe, tag, or point at another saved secret | PATCH /v1/connections/:id |
connections_update_connection |
| Replace the credentials | POST /v1/connections/:id/credentials |
credential_store |
| Fill in address placeholders | PATCH /v1/connections/:id/path-params |
connections_set_connection_path_params |
| Set sync timing | POST /v1/connections/:id/cadence |
connections_set_connection_cadence |
| Read the API again, with a corrected address or sign-in | POST /v1/connections/:id/reinfer |
connections_reinfer_connection |
| Pause everything that moves data with this system | POST /v1/connections/:id/pause |
connections_pause_connection |
| Resume it | POST /v1/connections/:id/resume |
connections_resume_connection |
| See its history | GET /v1/connections/:id/audit |
connection_audit |
| Archive it | DELETE /v1/connections/:id |
connections_delete_connection |
Notes:
- Sync timing takes a
preset:realtime,5m,15m,hourly,daily,weeklyormanual. It applies to the system and to every flow that reads from it. - Replacing credentials is safe by default. Inferrex tests the new credentials against the system and only starts using them if the system accepts them. Otherwise the previous ones stay in use and the answer says why.
- Reading again a system that is already in use does not change what runs. The new reading is kept beside the live version until you approve it (
POST /v1/connections/:id/reinference/approve) or discard it (DELETE /v1/connections/:id/reinference). - Archiving is refused while a flow still uses the system. Archive the flow first. History is kept.
Next: objects and mappings.