Docs

One endpoint,
every model.

Tare is an OpenAI-compatible gateway in front of every model you use — ours and the ones you bring yourself. One base URL, one key, and every token accounted for.

Upstream channelsLocal Nodes

Local Nodes

A Local Node is a small agent you run inside your own network. It does two things for your own (BYOK) channels:

  • Egress from your network. Calls you make to Tare's endpoint for a channel marked LOCAL_NODE are handed to the node over its tunnel and leave from your machine instead of Tare's servers, useful when your upstream only accepts traffic from an IP you control or have whitelisted with your provider.
  • A local endpoint. Your application can also call the node directly: /v1/chat/completions /v1/completions and /v1/embeddings (OpenAI shape, Azure OpenAI paths included), plus /v1/messages (Anthropic Messages API), /v1/responses (OpenAI Responses API), /v1beta/models/{model}:generateContent (Google Gemini, Vertex AI paths included) and /model/{model}/converse (AWS Bedrock, with the Anthropic shape on InvokeModel) on 127.0.0.1:8090. Each vendor's SDK can be pointed at the node directly; streaming and tool calls are supported. The node runs each call by your own routes: channels marked LOCAL_NODE go from the node to the upstream without passing through Tare, while platform models and channels on the default direct egress are handed back to Tare automatically, with the same result and billing as calling Tare. Routing candidates, prices, data-protection rules and your account state are pushed to the node over its tunnel and kept current while it's connected; the node reports what it served, and Tare does the billing.

If you'd rather not run one yourself, use the official node; see "Not running your own: the official node" below.

The three request paths

PathEndpoint calledPasses through TareChannel selected byEgress
Tare's endpoint, channel set to LOCAL_NODEtare.jamerly.aiYes. Tare selects the channel and hands the request to the node over the tunnel; the response returns through TareTare, per requestnode
The node directly, channel set to LOCAL_NODE127.0.0.1:8090No. The node selects from its local candidate list and calls the upstream; the response returns directlynode, in the order pushed by Tarenode
The node directly, platform channels, default direct channels, or channels marked "always execute through Tare"127.0.0.1:8090Yes. The node hands the call to Tare with the caller's key, and Tare calls the upstreamTare, by the caller's routes (one of your own channels is named explicitly)Tare

On the second path Tare takes no part in the request. Candidates, prices, data-protection rules and account state are pushed to the node over the long-lived connection whenever configuration changes (a route or channel edit, a circuit opening or closing, a balance change) and stored locally; each request reads the local copy and moves to the next candidate when the first fails. Latency on this path is the node-to-upstream leg only, and the node keeps serving while Tare is unreachable (see below).

The third path needs no setup: the addresses and keys of platform channels and default direct channels are never sent to your machine, so direct calls on the node hand them back to Tare automatically. On your own node, "always execute through Tare" behaves the same as the default direct egress; the difference shows only on the official node, where default direct channels go out from the official node while marked channels still leave from Tare, for upstreams that accept Tare's egress address only. LOCAL_NODE and "always execute through Tare" cannot both be set on one channel: the egress of the first is the node, the egress of the second is Tare, and setting both would route a request from the node to Tare and back.

Not running your own: the official node

The official node is the same agent, operated by Tare, at https://tare-node.jamerly.ai. Nothing to install and no registration token: point your SDK at https://tare-node.jamerly.ai instead of http://127.0.0.1:8090 (for the OpenAI SDK, base_url is https://tare-node.jamerly.ai/v1) and send one of your own Tare API keys. It accepts the same request shapes and model names as described in "Calling the node directly" below. Platform channels and default direct channels are sent from the official node; channels marked LOCAL_NODE (which must leave from your network) and channels marked "always execute through Tare" are handed back to Tare. Usage is recorded against your key and account and billed exactly as a call to Tare.

Setting one up

There is no Docker image you can pull for this: the container build is internal, published to a registry your credentials don't reach. The binary is the only path that actually works, on Linux/amd64:

  1. Download and unpack the agent on the machine that will run it:
Code / Terminal
curl -fLO https://s.jamerly.ai/tare-local-node/stable/tare-local-node-linux-amd64.tar.gz
tar xzf tare-local-node-linux-amd64.tar.gz
  1. Console → Local Nodes → Generate registration token. Shown once, like a key, so copy it immediately. It is single-use and expires in 24 hours.
  2. Start it with that token and any inference key on your account:
Code / Terminal
TARE_CONTROL_BASE_URL=https://tare.jamerly.ai TARE_TUNNEL_ADDR=tare-tunnel.jamerly.ai:9090 TARE_REGISTRATION_TOKEN=<TOKEN FROM STEP 2> TARE_API_KEY=<YOUR OWN API KEY> ./tare-local-node

Leave /api off TARE_CONTROL_BASE_URL. The tunnel goes to a public hostname, so the node uses TLS for it automatically (TARE_TUNNEL_TLS=auto).

On success it writes long-lived credentials to /etc/tare-local-node/credentials.json and registers itself, which is what makes it show up in the console. Restarts after that don't need the token again: it reads that file, and the token is already consumed regardless. 4. Console → Channels → edit one of your own channels → check "Route this channel through a local node instead of calling it directly". The second switch in the same box, "Always execute through Tare", works the other way: a direct call on the node for this channel is handed to Tare, and the node neither contacts the upstream nor holds its address or key. It is for upstreams that accept Tare's egress address only. The two switches are mutually exclusive. Four dialects in the endpoint dropdowns are served by local nodes only: Google Gemini / Vertex AI (URL …/models/{model}:generateContent, key in x-goog-api-key; a Vertex host takes an OAuth access token), Azure OpenAI (URL …/openai/deployments/{deployment}/chat/completions?api-version=…; the deployment segment is replaced by the model's upstream name), AWS Bedrock Converse (URL https://bedrock-runtime.{region}.amazonaws.com/model/{modelId}/converse; the key is either a Bedrock API key or ACCESS_KEY:SECRET_KEY for SigV4 signing) and OpenAI legacy completions. Calls to such a channel through Tare's endpoint are forwarded without translation. 5. Optionally, point your application at http://127.0.0.1:8090 on that machine. The OpenAI SDK uses /v1/chat/completions, /v1/completions or /v1/responses, and the AzureOpenAI client sets azure_endpoint; the Anthropic SDK uses /v1/messages; the Google GenAI SDK sets base_url (generateContent and streamGenerateContent); boto3's bedrock-runtime and the AnthropicBedrock client set endpoint_url, and request signatures are not checked. Model names are the same as against Tare. Limits: /v1/responses does not accept previous_response_id (the node keeps no conversation state; send the full input on each call); /v1/completions does not accept suffix; Bedrock's invoke accepts Anthropic Messages bodies only. GET /v1/models lists the models the node can route, in the shape of whichever SDK asks (OpenAI, Anthropic or Gemini), with the same context length, output limit, modality and price fields as Tare's catalog. Token counting (/v1/messages/count_tokens, Gemini's countTokens) is forwarded to the model's channel when that channel is a native Anthropic or Gemini endpoint, and answers 501 otherwise; the node does not estimate token counts itself. Calls to the node carry one of your own Tare API keys, in the place your SDK puts it (Authorization: Bearer, x-api-key, x-goog-api-key, api-key, or the access key of a SigV4 signature). By default the node verifies each caller with Tare (TARE_NODE_AUTH_MODE=resolve): the first time it sees a key it asks Tare over the tunnel and caches the answer for 60 seconds, and the key must belong to the account the node is registered to (otherwise 401). Disabled, expired or exhausted keys and keys restricted to other source IPs are refused exactly as on Tare's endpoint, the models offered are the ones the key's router can reach, and usage, credit limits and cost attribution are recorded per key. After 20 keys in a row from one source that Tare answers as invalid, further unseen keys from that source get 429 with Retry-After; keys already verified are unaffected. The older offline check against the key list Tare pushes is still available as TARE_NODE_AUTH_MODE=snapshot, with a warning at startup. TARE_NODE_LISTEN changes the bind address; TARE_NODE_AUTH=off disables the check and is accepted only for a loopback bind.

The node calls home every 20 seconds to prove it is alive, and refreshes the list of your channels that should route through it every 8 minutes using the inference key you gave it. That key is only ever used for this, never to make model calls on your behalf.

Calling the node directly

What is the same as calling Tare: model names, request and response shape, streaming (the node asks the upstream for usage on the final chunk so the call is billed correctly), the X-Generation-Id response header, and the entry in Call Traces with tokens and cost.

What is different:

Through Tare's endpointDirectly on the node
Channels consideredevery route of the model, platform channels includedevery route as well, in the order Tare ranks them; only LOCAL_NODE channels are sent from the node, the rest are handed back to Tare
Platform channels, default direct channels, channels marked "always execute through Tare"as usualthe node does not contact the upstream and holds neither its address nor its key; the call is handed to Tare with the caller's key, and Tare executes, bills and records it; the X-Generation-Id returned is Tare's
Upstream dialectsOpenAI-compatible, OpenAI Responses, Anthropicall of those plus Google Gemini / Vertex AI, Azure OpenAI, AWS Bedrock Converse and legacy text completions, as configured on the channel's endpoints; when your application speaks the same dialect as the channel, the request and response pass through untouched
Shapes your application can sendOpenAI Chat CompletionsOpenAI Chat Completions / legacy completions / Responses, Anthropic Messages, Google Gemini and Vertex AI, Azure OpenAI paths, AWS Bedrock Converse and InvokeModel (Anthropic shape)
/v1/images/generationsyes501 not_implemented
Model catalog (GET /v1/models)the models your key can callthe models this node can route, with the same fields; also served in the Anthropic and Gemini list shapes
Token counting (count_tokens, countTokens)not servedforwarded to the model's channel when it is a native Anthropic or Gemini endpoint; 501 otherwise
Failover between channelsyesyes, with the same failure classification; outcomes are reported back and count toward channel health everywhere
Data protectionscanned on Tarescanned on the node by the companion scan service (below)
Request and response bodies in Call Tracesper your retention settingnone for calls the node sends itself (the content does not reach Tare); calls handed back to Tare follow your retention setting
API keychecked on every callverified with Tare and cached for 60 seconds (default resolve mode); the same refusals, per-key usage and credit limits
Balance and limitschecked on every callchecked against the state last pushed to the node; the authoritative charge arrives after the call and corrects the node's running estimate

A model the calling key's router cannot reach answers 404 on the node. A blocked account answers 403, the same as on Tare; a missing or unknown key answers 401.

When the node can't reach Tare

The part of direct calls the node sends itself (LOCAL_NODE channels) keeps working on whatever the node was last told: candidates, prices, rules and account state as of the last push. Calls that need to be handed back to Tare fail during that window. Keys already verified are honoured for up to 10 more minutes; a key the node hasn't seen yet answers 503 (cannot be verified right now), not 401. Usage is held on the node and sent as soon as the tunnel is back (the most recent 10,000 reports are kept), and only then appears in Call Traces and on your statement. Calls made through Tare's endpoint during that window fall back as described in the warning below.

Data protection on the node

When DLP is enabled for your account, direct calls are scanned on the node by a companion scan service running next to it (TARE_DLP_SIDECAR_URL, default http://127.0.0.1:8098), with the account-level settings from the Security page (the account switch, your choice per type, recommended rules); per-key settings never apply here because a direct call carries no key. Masked text is what reaches the upstream, and a block answers 403 naming the entity type, like on Tare. If rules are in effect and the scan service isn't reachable, the node refuses the call (503) rather than forwarding it unscanned. With DLP off for your account no scan service is needed.

The scan service ships as its own package, Linux/amd64, with its runtime included:

Code / Terminal
curl -fLO https://s.jamerly.ai/tare-local-node/stable/tare-dlp-sidecar-linux-amd64.tar.gz
tar xzf tare-dlp-sidecar-linux-amd64.tar.gz
./tare-dlp-sidecar/bin/tare-dlp-sidecar

It listens on 127.0.0.1:8098, which is where the node looks by default; TARE_DLP_SIDECAR_PORT on the service and TARE_DLP_SIDECAR_URL on the node change that together. Keep it on the same machine as the node. Name, location and organization detection use a local language model that is downloaded from s.jamerly.ai on first use (about 180 MB; TARE_DLP_NER_BASE_URL points it at a mirror of your own) and takes a couple of minutes to load. While it loads, requests are still scanned for every other type and forwarded; those three types start being detected once the model is ready. Give the service 2 GB of heap when those three types are on (TARE_DLP_SIDECAR_HEAP=2g); with them off, nothing is downloaded.

What the console shows

  • Registration tokens: every one ever issued, with status (Pending / Used / Expired) and, once used, which node it became. Only a short fingerprint is shown after issuance, never the token itself again.
  • Nodes: each registered node's status (Online / Offline / Registering / Revoked), agent version, and last heartbeat. A separate "Tunnel connected" indicator reflects whether the live connection is up right now; the two can disagree for a few seconds right after a disconnect.

Console-session only, same as Channels and Routing: POST/GET /v1/node/registration-tokens (issue one, or list every one ever issued), GET /v1/node/nodes (list your registered nodes), POST /v1/node/revoke.

For calls made through Tare's endpoint, a node being offline does not block traffic: it silently falls back to calling the upstream directly, from Tare's own servers. The feature is meant to optimize the path, not add a new way for a channel to become unavailable, but it means the guarantee "this traffic only ever leaves from my own network" does not hold across a node outage. If that's why you're using this, a source-IP restriction your upstream enforces, an outage defeats it silently rather than failing loudly. There is no setting today that turns this into a hard requirement instead of a preference. Calls made directly on the node never fall back; if the node is down they simply fail.

Revoking a node

Console → Local Nodes → revoke. Effective immediately for new requests: a revoked node is never selected again, regardless of whether its process is still running. It does not forcibly close a connection already in progress; if the agent process happens to still be up, it just stops being sent any new work. To use that network again, register a fresh token; a revoked node's identity cannot be revived.

Things worth knowing before relying on this

  • Only your own (BYOK) channels can use a local node. A platform-shared channel never can.
  • Checking "Route this channel through a local node" on the Channels page is all it takes; no separate approval. It writes both the LOCAL_NODE egress mode and allowLocalEgress: true. A channel view showing allowLocalEgress: false (which only happens for data not written through the console) means calls still run direct and the channel is not pushed to the node; check the box again in the console to fix it.
  • Channels marked "always execute through Tare": the node does not contact the vendor; traffic leaves from Tare's egress, as it does for a call to Tare's endpoint.
  • Registering more than one node adds real capacity: each call through Tare is sent to a randomly chosen node that's currently connected, so traffic actually spreads across all of them. This isn't load-aware yet: it doesn't know how busy a node already is, so an uneven mix of short and long calls won't split evenly. If every node you registered is offline, the call falls back the same way a single node going offline does (see the warning above).
  • Changes you make in the console reach a connected node within seconds: adding or editing a channel or route, a channel being parked or recovering, your balance running out, a data-protection rule change. A node that was disconnected gets a full refresh when it reconnects.
  • The registration token and the node's own credentials are never displayed or retrievable after their one-time reveal; losing them means generating a new token and re-registering.
Docs last updated Oct 17, 2026, 23:03 (UTC+8)