E-Invoice API
Guides

Sandbox and live

One base URL, two environments, selected by your key prefix.

There is one base URL:

https://staging-api-e-invoice.officefreund.de/api/v1.8.2

No sandbox subdomain, no ?mode=test, no environment header. Which environment you reach is decided entirely by the key you send:

Key prefixReachesCounts against
of_test_Sandboxyour sandbox allowance, at a lower rate limit
of_live_Liveyour production allowance

Switching environments means changing one string in your config. There is no second URL to keep in sync, and no way to point at the live service by accident while still holding a test key.

Why it is safe to decide this from the key

The prefix is only how the request is routed. It is not what makes the separation trustworthy — a prefix is just text, and text can be forged.

What makes it hold is that the routing decision is checked again, further in. The gateway independently derives the environment from the key, compares it against the environment recorded for that key when it was issued, and compares both against which service the request was actually routed to. If any of the three disagree the request is rejected with ENV_MISMATCH and never reaches the upstream.

So a forged of_live_ prefix does not get you into the live service — it gets you a 401, because the key behind it is not a live key. And a genuine test key that somehow arrives at the live service is rejected there too, rather than being quietly processed.

What differs in the sandbox

  • Lower rate limit. The sandbox is a public surface — this site's playground calls it — so it is capped harder than a live key.
  • Separate quota. Sandbox calls do not consume your production allowance.

That is the whole list. Both environments are served by the same Mustang engine, so a sandbox call really converts and really validates your document: paths, request bodies, content types, status codes, error shapes, headers and the documents you get back all behave the same. A request that works in the sandbox works live.

The playground on every endpoint page sends real requests to the real URL above. Paste an of_test_ key into it and you are exercising the exact path your production code will take.

On this page