Programmatic access to Liquid State's market intelligence, market data, and — with explicit high-sensitivity scopes — your own portfolio, thesis, decision and investment-process records. Read + draft-only writes: nothing an external client creates becomes a final record without your confirmation inside Liquid State, and there is no trading, custody, or execution capability of any kind. Information only — not financial advice.
curl -H "Authorization: Bearer $LIQUID_STATE_API_KEY" \ "https://www.liquidstate.tech/api/v1/platform/entities?q=eth"
Every response uses the envelope { ok, data, meta: { requestId, apiVersion, simulated?, stale?, dataCutoffAt? }, warnings? }. Simulated or stale data is always labeled — never presented as live.
OpenAPI spec: GET /api/v1/platform/openapi.json
Authorization: Bearer lsk_… (or X-API-Key). Keys are scoped; the full catalog with sensitivity classes is in the OpenAPI spec (x-scopes) and the key-creation UI. Free accounts get public-intelligence + market-data scopes (1 key, 1,000 requests/day); paid tiers unlock private portfolio/thesis/decision/investment scopes, production keys, draft tools, async jobs and higher quotas — see commercial licensing for products serving your own users. Entitlements are re-checked on every request — a downgraded account's old key loses private scopes immediately.
Errors: { ok:false, error: { code, message } } with codes such as authentication_required, invalid_api_key, expired_api_key, revoked_api_key, missing_scope, entitlement_required, rate_limited, not_found, validation_error, confirmation_required, licensing_restricted, internal_error (no stack traces, ever). Rate limits are per-key/minute and per-user/day by endpoint category; X-RateLimit-* and X-Request-Id headers are returned on every response.
POST /api/v1/platform/drafts with { actionType, payload, summary? } (action types: draft_investment_memo, draft_research_question, draft_thesis_version, draft_intelligence_agent, draft_research_report, draft_decision_review, …). The response is always status: "draft", requiresConfirmation: true plus a confirmation path (/member/developer#confirmations), warnings, missing information and a 24-hour expiry. Confirmation is bound to the exact draft hash, single-use, time-limited, and only possible from your authenticated Liquid State session — there is no API parameter that finalizes a draft. Revoking the creating key cancels its pending confirmations.
POST /jobs (jobType: research_report, portfolio_intelligence_package, period_comparison; Idempotency-Key header supported) returns 202, then GET /jobs/:id until a terminal status. Job results expire after 7 days.
Create endpoints on /member/developer or via POST /webhook-endpoints (scope webhooks:manage). Public HTTPS URLs only — localhost, private ranges and cloud-metadata addresses are rejected, and every delivery re-resolves and pins the destination IP (DNS-rebinding safe). Payloads are minimal resource references, never full private content. Test deliveries are labeled test: true.
Verify signatures (HMAC-SHA256 over "{timestamp}.{rawBody}"):
import { verifyWebhookSignature } from '@liquidstate/sdk';
const ok = verifyWebhookSignature({
secret: process.env.LS_WEBHOOK_SECRET,
rawBody,
timestamp: req.headers['x-liquidstate-timestamp'],
signature: req.headers['x-liquidstate-signature'], // "v1=<hex>"
}); // rejects tampered payloads and timestamps older than ±300sRetries: 1, 5, 30, 120 minutes; endpoints auto-disable after 10 consecutive failures (re-enable from settings). Delivery history is visible per endpoint.
No-code: Zapier's generic “Webhooks by Zapier → Catch Hook” trigger issues a URL you can paste straight into the webhook form — no custom Zapier app, no review process on either side. Full walkthrough: /integrations/zapier.
The first-party MCP server lives at https://www.liquidstate.tech/api/mcp (Streamable HTTP). Create a dedicated key for each MCP client, then:
{
"mcpServers": {
"liquidstate": {
"type": "http",
"url": "https://www.liquidstate.tech/api/mcp",
"headers": { "Authorization": "Bearer YOUR_LSK_KEY_HERE" }
}
}
}Claude Code CLI:
claude mcp add --transport http liquidstate https://www.liquidstate.tech/api/mcp --header "Authorization: Bearer YOUR_LSK_KEY"
Safe first questions: “What materially changed for my portfolio today?”, “Show new contradictory evidence affecting my ETH thesis.”, “Prepare a draft Decision Review package.” (drafts land on /member/developer for your approval). Revoke the key in settings to disconnect instantly; every tool call is in your integration activity log. MCP tools can never trade, move assets, or change holdings, a Risk Budget, a thesis, an approval, or an Action Plan — structurally, not by prompt.
@liquidstate/sdk (source in the repo at sdk/typescript; not yet published to npm):
import { LiquidStateClient } from '@liquidstate/sdk';
const client = new LiquidStateClient({ apiKey: process.env.LIQUID_STATE_API_KEY });
const events = await client.events.list({ entityId: 'demo-ent-eth', limit: 20 });
const draft = await client.drafts.create('draft_research_question', {
workspaceId: 'ws_…', question: 'What invalidates the L2 fee thesis?',
});
console.log(draft.data.confirmationPath); // approve inside Liquid StateReads auto-retry on 429/5xx; draft/job creation is only retried when you pass an idempotencyKey. The SDK never logs your key.
Keys: hashed at rest, constant-time compared, one-time display, expiring, rotatable — Revoke stops access immediately and cancels pending confirmations. Webhook secrets: hashed + AES-256-GCM encrypted, never shown again, never logged. Everything an integration does is audited in your integration activity log (secrets and private payloads excluded). Data covered by provider licensing that can't be redistributed returns licensing_restricted — it is never exposed or fabricated.
Information only, not financial advice · read + draft-only writes · no trading, custody or execution capability of any kind