Skip to content

Authentication and environments

Every request carries an API key as a bearer token, in the header Authorization: Bearer mw_test_…. A missing, malformed, unknown or revoked key gets 401 with the error type authentication_error.

Terminal window
curl "$MIDWATER_BASE_URL/v1/agents/default/health" \
-H "Authorization: Bearer $MIDWATER_API_KEY"

Your Midwater workspace holds one or more projects. Each project has two environments:

Environment Key prefix Use it for
Test mw_test_ Practice calls while you build and try things out
Live mw_live_ Your agents’ real calls

Keys made before October 2026 start vk_ and still work.

A key belongs to exactly one environment of one project, and everything it sends or reads stays there:

  • Conversations sent with a test key appear only under Test in the app and never reach live reports or alerts.
  • GET /v1/conversations/{id} finds only conversations in the key’s environment; anything else is 404.
  • Agent and group health is measured per environment. A test key reads test health, and the response says "environment": "test".
  • Agents and groups belong to the project, so the same agent.id names the same agent in both environments.
  • Webhooks fire for live conversations. A destination or route can opt in to test conversations; those events carry "environment": "test".

Make keys on the Developers page in the Midwater app. Making keys needs the Admin or Owner role in the workspace.

A key is shown once, when you create it. Midwater stores only a hash, so a lost key can’t be recovered, only replaced. Revoking a key takes effect on the next request.

To rotate a key: make a new one, deploy it, check on the Developers page that the new key is being used, then revoke the old one.

The base URL is a variable: use the base URL for your Midwater environment. Every example in these docs reads it from MIDWATER_BASE_URL, and both SDKs require it (as an argument or from MIDWATER_BASE_URL); neither has a default host.

The API version is in the path: /v1. New fields, endpoints, event types and enum values can appear without a new version, so accept values you don’t recognise and ignore fields you don’t use. A breaking change would get /v2, and /v1 would keep working alongside it for at least 6 months.