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, ...) — installs as the meridian command; see meridian-cli/README.md (not to be confused with the unrelated meridian-cli package also on PyPI). No chat loop, no personas; it's a management CLI over the API, 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.2.0

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.2.0
File Size Uploaded Provenance
meridian_client-0.2.0.tar.gz 16.2 kB Without provenance Details

Built distribution (wheel)

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

Total release size: 29.9 kB

Release files / meridian_client-0.2.0.tar.gz

Download URL meridian_client-0.2.0.tar.gz
Size 16.2 kB
Tags Source
SHA-256 checksum
How to use checksums
2392fc8053bfc199407e36e974fe7e19c5bb50ef22ab967359fdb361696bcc41
BLAKE2b-256 checksum
How to use checksums
7eeda0e0e0542a3c07bad8f1fcbaa747dde326e9fa220995b33d710a9b229956
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.2.0-py3-none-any.whl

Download URL meridian_client-0.2.0-py3-none-any.whl
Size 13.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7bc8ab049d8930eddadb71303be1ba757293b19a2a58e7ca2ffc67061e7b0e2d
BLAKE2b-256 checksum
How to use checksums
a94ff5f90d19800daf962bae90d6bc58ec48d5b6a9cd9a5ed6327c0c71b3c2df
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.2.0

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