OXYGENOxygen/ Docs
Providers

Custom HTTP integrations

Turn any HTTP API into catalog tools with a JSON manifest.

A custom HTTP integration registers your own HTTP API as provider tools. Each operation you declare becomes a callable tool (custom_http.<slug>.<operation>) usable from tool columns, workflows, and recipes, with the credential injected server-side.

Use it when the recipe-native HTTP tools are not enough: oxygen.http_json_request (GET) and oxygen.http_json_post (POST with JSON body) only reach anonymous public HTTPS endpoints — no credentials, no custom headers. Custom HTTP operations support GET, POST, PUT, PATCH, and DELETE with typed body/query/path fields and stored credentials.

Registering

oxygen custom-integrations apply --manifest ./my-integration.json --json
oxygen custom-integrations list --json

apply requires exactly one of --manifest <path> (a JSON file) or --manifest-json '<json>' (inline). Credentials are not passed here — see Credentials.

Manifest shape

{
  "version": 1,
  "slug": "lead_scorer",
  "name": "Lead Scorer",
  "description": "Score leads via our internal API.",
  "baseUrl": "https://api.example.com/",
  "auth": { "type": "bearer" },
  "operations": [
    {
      "operation": "score_lead",
      "displayName": "Score Lead",
      "method": "POST",
      "path": "/score",
      "summary": "Score a lead by email.",
      "effect": "read",
      "fields": [
        { "key": "email", "type": "string", "required": true, "description": "Lead email.", "location": "body" }
      ]
    }
  ]
}

This mints the tool custom_http.lead_scorer.score_lead.

Top-level fields

FieldRequiredNotes
versionNoDefaults to 1; must be 1 if set.
slugYesIntegration id. Must match ^[a-z][a-z0-9_]{0,62}$.
nameYesDisplay name.
descriptionNoDefaults to a generated description.
baseUrlYesPublic HTTPS URL. Private/internal hosts are rejected.
authNoDefaults to { "type": "none" }. See Auth.
operationsYesNon-empty array. Operation ids must be unique.

Operation fields

FieldRequiredNotes
operationYesOperation id, same slug rules as above.
methodYesGET, POST, PUT, PATCH, or DELETE.
pathYesMust start with /. Appended to baseUrl; supports {param} segments filled by location: "path" fields.
displayNameNoDefaults to a titleized operation id.
summaryNoDefaults to <METHOD> <path>.
effectNoread (default) or write. Writes follow approval rules.
sideEffectClassNoDerived from effect unless set.
fieldsNoTyped inputs — see below. With no fields, a GET forwards the raw input as query params and other methods forward it as the JSON body.
timeoutMsNoDefault 10000, max 30000.
maxResponseBytesNoDefault 1000000, max 5000000.
outputPathNoDot-path to project out of the response.
inputSchema / outputSchemaNoOptional JSON Schemas for the tool descriptor.

Field entries

FieldRequiredNotes
keyYesInput name (slug rules).
typeNostring (default), number, boolean, string[], number[], object, object[], array. integer is accepted as an alias for number.
requiredNoDefaults to true.
descriptionNoDefaults to the key.
locationNobody, query, or path. Defaults to query on GET, otherwise body.
wireKeyNoRename the key on the wire.

Auth

auth.typeExtra fieldsSent as
none
bearerAuthorization: Bearer <secret>
api_key_headerheader, prefix?<header>: <prefix><secret>
api_key_queryparam?<param>=<secret>
basicusernameAuthorization: Basic base64(<username>:<secret>)

Credentials

The manifest never contains the secret (apply rejects a secrets field). After apply, attach the token/key from the terminal:

oxygen custom-integrations connect lead_scorer --secrets-file ./.env

--secrets-file reads a .env-style file (a single entry, or one named API_KEY/TOKEN/PASSWORD/SECRET) so the credential stays out of shell history. You can also attach the credential from the web Connections page (/connections/custom_http). Either way, Oxygen stores the credential encrypted and injects it server-side at call time — recipe and column code never sees it, and it never enters a recipe bundle or run log.

Calling the tools

oxygen tools get custom_http.lead_scorer.score_lead --json
oxygen tools run custom_http.lead_scorer.score_lead --input-json '{"email":"a@b.com"}' --mode dry-run --json

In a recipe, allowlist the tool id and call it with ctx.tools.run("custom_http.lead_scorer.score_lead", { email }, { key }). In a table, bind it as a tool column.

Custom integration vs. local HTTP column

Two different things share the "Custom HTTP" name. Pick by where the credential must live:

A. Reusable custom integration (this page). oxygen custom-integrations apply registers org-wide custom_http.<slug>.<operation> tools; the credential is stored encrypted in Oxygen, and the tools run in the background from tool columns, workflows, and recipes with billing and provenance.

B. Local HTTP column (the web app's "Add column → HTTP API"). A single tool column whose definition uses mode: "custom_http" with an inline request block; its secrets name local environment variables, so it executes only in your own CLI process via oxygen columns run <table> <column> --local — never server-side, never in the background.

Use B only when the key must not leave your machine.

  • Integrations — connection state and auth modes.
  • Recipes — calling custom tools from workflow code.
  • Approvals — write-effect operations and live runs.

On this page