Skip to main content

name: meridian-integration description: How to call Meridian (the governance router) correctly from a new, standalone client — auth, the onboarding sequence, and what's still house/console-only.

Integrating with Meridian

Meridian is a policy-governed inference router: you ask it "which model should agent_name use right now", and it answers using project/agent policy (quality, cost, risk, allowed/denied hubs, data classification) rather than you hardcoding a model name. It knows nothing about MTA specifically — any client that holds a valid key can use it standalone.

Full generated route-by-route reference: docs/api/api-reference.md in this repo (regenerate with python3 scripts/gen_api_docs.py after any route change — it reads the live FastAPI app, so it can't go stale the way a hand-written doc can).

Install

pip install meridian-client          # published — the normal path, or
pip install -e meridian-client/      # editable, from this repo (contributing to the SDK itself)

Prefer a terminal to Python? pip install meridian-governance-cli wraps this same SDK as subcommands (meridian signup, meridian resolve my_agent, meridian keys list, meridian hubs discover, ...) — installs as the meridian command; see meridian-cli/README.md (not to be confused with the unrelated meridian-cli package also on PyPI). One exception to "just subcommands over the API": meridian chat drives a governed resolve -> dispatch -> audit loop interactively or scripted (--one-shot, --daemon), with /code and /manage modes inside the REPL — everything else stays a thin management layer, not a clone of mta-cli's consumer-companion command set.

Auth — read this before anything else

Meridian accepts a key two ways; it doesn't matter which:

Authorization: Bearer mdn_xxxxxxxx
x-api-key: mdn_xxxxxxxx

With no key at all: on-prem only, and only if that instance was started without MERIDIAN_AUTH_REQUIRED=true. The request resolves to the instance's single default org. Every cloud deployment (dev-meridian.mytrustworthy.ai and any other MERIDIAN_DEPLOYMENT=cloud instance) requires a key — no key gets a flat 401, not a default org.

Getting your first key

from meridian import Meridian

m = Meridian.signup("https://dev-meridian.mytrustworthy.ai",
    org_name="my-project", email="me@example.com", password="...")
# m is now an authenticated client. m.org_id and m.signup_response are set.

One call: creates a new org (always free tier — self-serve can't grant itself more than that), its first user, and its first key, and returns a Meridian already authenticated with it. This is the only unauthenticated write on the whole API — everywhere else, minting a key or registering a user needs an org_id that a cold caller doesn't have yet, which is exactly the chicken-and-egg problem this one call exists to break.

If you already have a key (an account team provisioned you directly, or you're adding a second client to an org that already signed up):

m = Meridian("https://dev-meridian.mytrustworthy.ai", api_key="mdn_...")

Three tiers, one engine

There's one governance engine underneath all of this — the tiers below are just how much of it you choose to use, not three different products:

  • Individual / fast start: pin a model and go. pinned_model skips scoring entirely (resolver.py's "Step 3: Pinned model — skip scoring") — deterministic, zero policy to configure.
  • Business / small team: the quality/cost/risk sliders. Same create_agent call, just set overrides instead of (or in addition to) a pin; invite teammates into the same org via POST /api/v1/auth/register once you're authenticated.
  • Enterprise / custom governance: change-requests and approval (create_change_request → approve_change_request), hub allow/denylists, data classification enforcement (pii hard-forces risk to 1, on-prem only). All already built; nothing here is Enterprise-only code, just the parts a fast-start integration doesn't need to touch.

The onboarding sequence

A tenant key can do all of this itself — no console needed past signup:

# 1. A project: your governance boundary. One org can have many.
project = m.create_project(
    org_id=m.org_id,
    name="my-standalone-agent",
    quality=7, cost=5, risk=5,          # 0-10 sliders, project-level defaults
    classification="general",            # "pii" forces risk=1 regardless of the slider
)

# 2. An agent inside it. This is the identity you resolve against — not a
#    user, not an API key, an AGENT. One project can have many, each with its
#    own overrides.
agent = m.create_agent(
    project.id, "my_agent",
    quality_override=9,                  # omit to inherit the project default
    allowed_hubs=["anthropic-direct", "bedrock"],  # omit for no hub restriction
)

# 3. Resolve. Call this every time you're about to make an inference call —
#    it's cheap, and policy can change between calls.
decision = m.resolve("my_agent", project_id=project.id)
print(decision.model, decision.hub)      # e.g. "claude-opus-5" "anthropic-direct"

# 4. After the real inference call, report usage so cost tracking means
#    something.
m.audit(decision.routing_log_id, input_tokens=512, output_tokens=128,
         latency_ms=840)

That's the whole golden path. m.explain(decision.routing_log_id) gets you the full candidate breakdown (every model considered, why each one was eliminated or scored where it scored) if you need to show your work.

Without the SDK (raw HTTP)

curl -X POST https://dev-meridian.mytrustworthy.ai/api/v1/resolve \
  -H "Authorization: Bearer mdn_..." -H "Content-Type: application/json" \
  -d '{"agent_name": "my_agent", "project_id": 123}'

Every route in docs/api/api-reference.md works the same way — method, path, JSON body of the fields listed, same two auth headers.

What a tenant key cannot do (yet)

docs/api/api-reference.md marks every route tenant key: yes/no. The "no" routes answer 403 "This route is not yet tenant-scoped; refused for tenant keys" regardless of whether your key is valid — it's a blanket refusal by path, not a permission check. As of this writing that's mainly: hub/model/deployment registration and edits, org creation and edits, and most cost/governance console views. Those need a house key or the console. Project and agent create/update/delete, resolve, audit, explain, simulate, and change-requests are all tenant-reachable.

Gotchas

  • PUT /api/v1/projects/{id}/lifecycle is a stub. It validates the request and echoes the current row back — it does not change anything. Don't build on it (meridian#7's predecessor finding).
  • The SDK's response objects have an .extra dict. Every typed field the SDK knows about is a real attribute (agent.allowed_hubs); anything the server returns that this SDK version doesn't model yet lands in agent.extra instead of silently vanishing. If a field you expect is None, check .extra before assuming the server didn't send it.
  • resolve_failover only writes an audit record if you pass agent_name. Without it you get a plain hub-allowlist fallback with no governance and no audit trail — fine for "just get me anything that works", wrong for anything that needs to explain itself later.
  • Tool-access governance does not exist yet. Meridian governs which model an agent may use. It does not yet govern which tools an agent may call — there's no route for it, and the schema slots for it (agent.agent_tools, agent.skill_ids) are unpopulated. If your new agent needs Meridian to gate tool access rather than just model choice, that's a real gap, not a documentation gap — see obsidian-vault-kb/relays/meridian/2026-10-12-should-meridian-govern-tools-and-what-that-costs-in-apis.md for the live design discussion.
  • Forgot a built-in-auth password? POST /auth/forgot-password / POST /auth/reset-password (meridian#10), also reachable from the console's "Forgot password?" link. Requires RESEND_API_KEY to actually be configured on the instance — without it the request fails loudly rather than handing the token back in the response. That's deliberate: an earlier version of this capability did exactly that and was removed on 2026-09-12 because it let anyone who knew an email address take over that account. There is no magic-link login — only password reset; you still need to know a password to sign in, the email only proves you own the inbox.

Metadata

Release files for meridian-client 0.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for meridian-client 0.3.1
File Size Uploaded Provenance
meridian_client-0.3.1.tar.gz 18.0 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for meridian-client 0.3.1
File Interpreter ABI Platform
meridian_client-0.3.1-py3-none-any.whl Python 3 none any Details

Total release size: 32.4 kB

Release files / meridian_client-0.3.1.tar.gz

Download URL meridian_client-0.3.1.tar.gz
Size 18.0 kB
Tags Source
SHA-256 checksum
How to use checksums
3797bffd5746ca4c13ad4a2efaf6bd08510a5fbe03e9e49663649118729c6eb1
BLAKE2b-256 checksum
How to use checksums
42fda9532b945d90b53fbb78f90e79a75e1b3dece3ac8a26b276a746a0b383fb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / meridian_client-0.3.1-py3-none-any.whl

Download URL meridian_client-0.3.1-py3-none-any.whl
Size 14.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4e38143368b737a2ac6c98ffdd15db0bc089b442e931e066fb537ac8a729789c
BLAKE2b-256 checksum
How to use checksums
e5fd749821e66b4d1537dc31be21d7e8dac0b376783f5194013d7190ab4bea11
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Security for meridian-client 0.3.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page