BYO LLM Key Management via API

Save, Test, and Manage Your Own LLM Provider Keys — Real Encryption, Real Security Guarantees

COMPLETE GUIDE

Building with the API? Open the developer docs

Finmagine API & MCP — free tier to test • Pro/Max for full access • REST + MCP

Open the Docs →
← API & Agent Integration Hub ← All Feature Guides
Published: July 29, 2026  |  9 min read  |  Developer Guide  |  API & Agent Integration Series

Multimedia Learning Hub

Master BYO LLM key management through a complete learning overview and interactive flashcards

What You Will Master

Both the Investment Committee and Strategy Lab Research Presets need a real LLM provider to run — and Finmagine never bills its own LLM spend to you for those features. Instead, you bring your own provider key (BYO). This guide covers the 5 API/MCP operations that manage that key end to end, and — because a provider API key is a genuine secret — the real security engineering behind how it's stored, transmitted, and audited.

What This Guide Covers:

  1. The 5 Operations — list, save, test, set-preferred, and remove
  2. The 6 Supported Providers — including a genuinely surprising one about DeepSeek
  3. How Your Key Is Actually Stored — real encryption, not just "we encrypt it, trust us"
  4. The Security Design Around These Endpoints — header-only auth, independent rate limits, audit logging
  5. Save vs. Test vs. Test-and-Save — and the important "NOT atomic" nuance
  6. Setting a Preferred Provider — account default vs. per-call override
  7. Why the REST Endpoint Is Safer Than MCP for the actual secret

Who This Is For:

  • Anyone about to run their first Investment Committee or Research Preset — this is the required prerequisite step
  • Security-conscious developers — evaluate exactly how a third-party platform handles your provider secrets before trusting it with one
  • Agent builders — understand the specific MCP-logging risk these endpoints' own tool descriptions warn about

Test Your Knowledge

Click any card to reveal the answer. Use the search box to find a specific topic.

The 5 Operations

All 5 live under /account/byo-key/* (plus one GET at /account/byo-keys), available as both REST and MCP, and — notably — none of them carry a subscription tier gate. Saving and managing a key is account configuration, not data consumption, so it's available on Free tier same as any paid tier.

OperationRESTMCP toolWhat it does
ListGET /account/byo-keyslist_byo_keysLists saved keys (masked) and the current preferred provider
SavePOST /account/byo-key/savesave_byo_keySaves or overwrites a key for one provider
TestPOST /account/byo-key/testtest_byo_keyLive-verifies a key against the real provider (~15s)
Set PreferredPOST /account/byo-key/set-preferredset_preferred_byo_keySets the account-wide default provider
RemovePOST /account/byo-key/removeremove_byo_keyDeletes a saved key (clears preferred if it was set)
Up to 5 provider keys can be saved simultaneously. You're not limited to one — save Anthropic and DeepSeek both, for instance, and switch which one a given call uses via the preferred-provider setting or a per-call hint, without re-entering a key each time.

The 6 Supported Providers

Provider IDDisplay NameDefault ModelReal Endpoint Called
anthropicClaude (Anthropic)claude-3-5-sonnet-20241022api.anthropic.com/v1/messages
openaiGPT (OpenAI)gpt-4o-miniapi.openai.com/v1/chat/completions
geminiGemini (Google)gemini-2.5-flashgenerativelanguage.googleapis.com
groqLlama (Groq)llama-3.3-70b-versatileapi.groq.com/openai/v1/chat/completions
deepseekDeepSeekdeepseek-v4-flashapi.deepseek.com/anthropic/v1/messages
openrouterOpenRoutergoogle/gemma-4-31b-it:freeopenrouter.ai/api/v1/chat/completions
DeepSeek's endpoint is genuinely worth knowing about. Despite being a distinct provider with its own API key and billing, DeepSeek exposes an Anthropic-compatible endpoint (/anthropic/v1/messages) rather than the OpenAI-style chat-completions shape every other non-Anthropic provider here uses. Finmagine's integration calls it exactly like Anthropic's own endpoint, just pointed at DeepSeek's host — worth remembering if you ever build your own DeepSeek integration elsewhere and wonder why the request shape looks like Claude's, not GPT's.

The model field is always user-editable at save time — the defaults above are presets, not hard requirements. OpenRouter's default specifically points at a free-tier model (:free suffix) so a first-time OpenRouter save doesn't accidentally assume a paid model.

SECURITY

How Your Key Is Actually Stored

A provider API key is a real secret — if it leaked, someone else could spend against your account with your provider. Here's exactly what happens to it, not a vague "we encrypt it" claim:

// What list_byo_keys actually returns — masked, never raw { "provider": "anthropic", "model": "claude-3-5-sonnet-20241022", "key_masked": "sk-ant-••••a1b2" }
The masking convention shows up to the first 6 characters, then a fixed ••••, then the real last 4 — enough to recognise which key is saved at a glance, never enough to reconstruct it.

The Security Design Around These Endpoints

These are the first credential-mutating endpoints on Finmagine's API, and they're deliberately held to a stricter standard than the normal per-tier request limits.

Header-only auth — query-param auth is rejected

Every other endpoint on the API accepts ?apiKey= as one of three valid auth methods. These 5 don't:

{ "error": true, "status": 401, "message": "This endpoint requires header-based auth (X-Api-Key or Authorization: Bearer) — ?apiKey= query param is not accepted here, since it can leak into logs/browser history." }
This is a real, deliberate exception — not an oversight. A query-string API key can end up in server access logs, browser history, or a shared screenshot far more easily than a header ever would. For an endpoint that's about to receive an even more sensitive secret (a provider key) in its request body, that risk gets closed off entirely rather than merely discouraged.

Independent, stricter rate limits

ActionLimitWhy
Save20/account/hourPrevents rapid key-cycling abuse
Test10/account/hourEach test makes a real, billable-to-you outbound call to your provider — capped independently of your normal API rate limit
test_and_save counts against the stricter 10/hour test quota, not the looser 20/hour save quota. A test-and-save call makes exactly the same real provider call a standalone test does — letting it slip through under the save quota alone would effectively allow 20 live verifications per hour instead of 10, quietly bypassing the limit that exists specifically to cap real outbound provider calls.

Audit logging — provider name only, never key material

Every save/test/remove action writes one row to an audit log: user, action, provider name, success flag, a hashed IP address (SHA-256, not the raw IP), and user agent. The raw or masked key itself is never written to this log — by design, the audit trail can prove that an action happened and which provider, without ever becoming a second place a leaked secret could be recovered from.

Email notification on key change

Saving a key fires a fire-and-forget security notification email to the account holder — "your BYO key for [provider] was just saved." It never blocks the API response if sending fails, but it does mean an unexpected key-save shows up in your inbox, not just silently in an audit table only you'd think to check.

Save vs. Test vs. Test-and-Save

ModeWhat it verifiesMakes a real provider call?
Save aloneFormat only (e.g. non-empty, matches expected shape) — not that the key actually worksNo
Test aloneLive-verifies an already-saved key, or an ad-hoc value, against the real providerYes (~15s)
Save with test_and_save: trueBoth — saves, then immediately live-verifies in the same callYes (~15s)
test_and_save is explicitly NOT atomic — the save always happens, even if verification is skipped. If your test-quota (10/hour) is already exhausted when you call save_byo_key with test_and_save: true, the key is still saved successfully — the response's test.error field explains that verification was skipped due to the rate limit, rather than failing the whole request. If you need to guarantee a key actually works before relying on it, check the response's test field rather than assuming saved: true alone means it's valid.

Re-testing without re-sending the secret

test_byo_key has a safer mode worth knowing about: pass just {provider} alone to re-verify the already-saved key — no secret is transmitted in that call at all, since the server reads its own stored (encrypted) copy. Passing {provider, model, key} tests an ad-hoc value instead, without saving it, but does require sending the raw key again.

Setting a Preferred Provider

set_preferred_byo_key sets an account-wide default — used whenever a Committee or Preset run doesn't specify which provider to use. It's deliberately an account default, not a per-task control.

If you run concurrent workflows and need a specific provider for one of them, pass a per-call provider hint instead of changing your account-wide preferred setting. Changing the account default mid-flight could race with another workflow already running under the old default — the per-call hint avoids that entirely, and is the recommended approach whenever a specific call needs to differ from your usual default.

Why the REST Endpoint Is Safer Than MCP for the Actual Secret

Both save_byo_key and test_byo_key (ad-hoc mode) carry an explicit warning baked directly into their MCP tool descriptions — visible to any agent or human reading the tool schema before calling it:

// From save_byo_key's actual tool description: "WARNING: this tool argument carries a real, secret provider API key in plain text. Do not send provider secrets through MCP clients you do not fully control — some clients log tool-call arguments. If unsure, save the key via the REST endpoint instead."

The concern is specific and real: some MCP client implementations log every tool call's arguments — for debugging, for conversation history, or for telemetry — and a provider API key passed as a plain-text tool argument would end up captured wherever that logging goes, entirely outside Finmagine's control.

PathRecommended for
REST endpoint directly (your own code, curl, the API Explorer)Actually saving or ad-hoc testing a raw key — not subject to an MCP client's own argument logging
MCP test_byo_key with {provider} onlyRe-verifying an already-saved key from within an agent conversation — safe, since no secret is transmitted in that call
MCP save_byo_key / ad-hoc test_byo_keyOnly in an MCP client you fully control and trust not to log arguments
If you're saving a key through Claude, Cursor, or any other MCP client, prefer the REST endpoint for that one action. Everything else about BYO key management — listing, setting preferred, removing, or re-testing an already-saved key — is equally safe through either REST or MCP, since none of those calls transmit the raw secret.

What's Next

With a provider key saved and verified, the next two guides cover what it's actually for:

See the API & Agent Integration hub for the full 12-guide roadmap.

Ready to Analyse Indian Stocks Like a Pro?

Finmagine gives you 30+ computed financial ratios, sector benchmarks, FII/DII flows, the Finmagine Score, and AI-powered analysis — all in one place.

Analyse a Stock → Create Free Account
← API & Agent Integration Hub ← All Feature Guides