Aller au contenu

EU-Resident Inference

Ce contenu n’est pas encore disponible dans votre langue.

If your agent processes a tenant’s name, a debtor’s address, or an invoice line item inside Germany, the model call is itself a data transfer. EU-resident inference is one more compliance rail your agent needs to operate here — alongside the ZAG exemption, Störerhaftung and GDPR handling you already get.

  • Not a cheap-token reseller. We are not competing on price per million tokens, and we will not win on that.
  • Not a frontier-model proxy. The catalogue is what EU providers actually host. If you need the largest US model, this is the wrong endpoint.
  • Not a replacement for your primary model. Use it for the calls that touch regulated data inside a German workflow, and keep whatever you already use for the rest.
  • A sub-agent summarises a debtor’s file before you call /v1/legal/inkasso.
  • A drafting step reads a tenant’s letter before you post it via /v1/letters.
  • Extracting line items from a customer document before /v1/invoices.

In each case the personal data is already inside a German legal process. Sending it to a US-hosted model puts an Art. 44 GDPR third-country transfer in the middle of that process, which you then have to paper over. Routing the call here keeps the whole chain in the EU.

Completions are served exclusively by these upstreams:

ProviderLegal entityProcessing region
Mistral AIMistral AI SAS, Paris, FranceFR (Paris)
IONOS AI Model HubIONOS Cloud GmbH, Montabaur, GermanyDE-TXL (Berlin)
Scaleway Generative APIsScaleway SAS, FranceFR-PAR (Paris)
OVHcloud AI EndpointsOVH SAS, Roubaix, FranceFR-GRA (Gravelines)

The guarantee is structural, not a policy statement:

  • Non-EU providers are absent by construction, not by preference. There is no US-domiciled entry in the routing table, no fallback list and no configuration switch that adds one. Changing that requires a code change that goes through review.
  • Fail-closed, not fail-over. If no EU upstream can serve a request, it returns 503 eu_upstream_unavailable. It never silently reroutes to keep the request alive.
  • Unknown models are refused outright. Asking for a model that is not in the EU catalogue returns 400 model_not_found — before any upstream is contacted and without spending credits.
  • Region is pinned per upstream. No cross-region spillover.
  • We only offer models whose processing location the provider states. Where a provider does not declare a datacentre country for a model, we do not serve it, however attractive its price.
  • Machine-verifiable. GET /.well-known/eu-inference.json returns each upstream’s legal entity, region and DPA link, plus the model→provider map. GET /v1/inference/models names the serving provider and region for every model.

Every completion also carries X-AGENTBUREAU-PROVIDER and X-AGENTBUREAU-REGION response headers, so you can assert residency per call rather than trusting a page.

EndpointMethodCost
/v1/inference/creditsPOSTx402 — buys a prepaid balance
/v1/inference/chat/completionsPOSTDebited from credits
/v1/inference/credits/{wallet_address}GETFree
/v1/inference/modelsGETFree
/v1/inference/chat/completions/dry-runPOSTFree — validates and quotes a ceiling

As with the rest of the API, prefix with /dev for Base Sepolia testnet.

1 — Buy credits. The same four-step x402 flow as every other endpoint.

Terminal window
curl -i -X POST https://agentbureau-api.datafortress.cloud/v1/inference/credits \
-H "Content-Type: application/json" \
-d '{"amount_usdc": 10.0, "nonce": "'"$(uuidgen)"'"}'
# 402, PAYMENT-REQUIRED: 10.00; USDC; eip155:8453; 0x...
# Transfer USDC on Base, sign "AgentBureau Intent: {intent_id}", then retry:
curl -X POST https://agentbureau-api.datafortress.cloud/v1/inference/credits \
-H "Content-Type: application/json" \
-H "PAYMENT-SIGNATURE: <tx_hash>" \
-H "PAYMENT-AUTHORIZATION: <signature>" \
-d '{"amount_usdc": 10.0, "nonce": "<same_nonce>"}'
# 200 {"balance_usdc":"10.000000","credit_key":"ab_sk_..."}

2 — Point any OpenAI-compatible client at it.

from openai import OpenAI
client = OpenAI(
base_url="https://agentbureau-api.datafortress.cloud/v1/inference/",
api_key=credit_key, # returned by the top-up above
)
response = client.chat.completions.create(
model="eu/mistral-small",
messages=[{"role": "user", "content": "Summarise this Mahnung."}],
)

Note the trailing slash on base_url — without it the OpenAI SDK’s URL join drops the last path segment and your requests will 404.

The credit_key is a payment receipt handle, not an account credential: no signup, no email, no dashboard, and it dies when the balance does. See Prepaid Credits for how it is minted, scoped and revoked, and for the signature-based alternative if you would rather hold no bearer token.

GET /v1/inference/models is the source of truth — the catalogue changes as EU providers ship and retire models. Each entry names the provider, its legal entity, the processing region and the current per-million-token price.

{
"id": "eu/mistral-small",
"owned_by": "Mistral AI",
"provider_legal_entity": "Mistral AI SAS, Paris, France (RCS Paris 952 418 325)",
"region": "FR (Paris)",
"context_window": 256000,
"price_usdc_per_1m_input": "0.150000",
"price_usdc_per_1m_output": "0.600000"
}

You are charged actual token usage at these rates plus margin, debited from your credit balance.

  • max_tokens is injected when you omit it. The credit hold needs a real ceiling, so a request without max_tokens gets the gateway default (4096). This differs from OpenAI’s default — set it explicitly if you care.
  • Streaming is not supported yet. stream: true returns 400 streaming_not_supported rather than silently ignoring the flag.
  • Unrecognised fields are forwarded. The request body is passed through to the upstream almost verbatim, so provider-supported features work without waiting for us to model them.
StatusCodeMeaning
402insufficient_creditsBalance cannot cover the request ceiling. Carries credit_topup_path.
402no_credentialNo credit key or signature presented.
400model_not_foundNot in the EU catalogue. No upstream was contacted, nothing charged.
400streaming_not_supportedSet stream: false or omit it.
503eu_upstream_unavailableNo EU upstream can serve this model. Fails closed; nothing charged.
502eu_upstream_errorThe EU upstream failed. The credit hold is released in full.