320px
Reference · v1.1.0

MCP reference

The 320px MCP server exposes contacts, campaigns, segments, and analytics as tools your agent can call directly. It speaks JSON-RPC 2.0 over HTTP and SSE. Every tool operates on a single organization, which is resolved implicitly from your API key.

Endpoint

POST https://api.320px.com/mcp
Content-Type: application/json
Authorization: Bearer <api_key>

Transports: http (single request/response) and sse (streaming). Server version is advertised in the initialize response under serverInfo.

Authentication

Every tools/call requires a bearer token. Three token shapes are accepted:

TokenScopeCan switch orgs?
Per-user API key
Studio → Settings → API Keys
Every organization the user is a member of. Yes — switch_organization works against any of the user's memberships.
Legacy org-scoped key
Created before user-linking was added
The single org the key was issued for. No — switch_organization returns an error.
Master key (PULSE_API_KEY)
Server-level secret, self-hosted only
All organizations in the system. Yes — any org by ID.

Unauthenticated methods: initialize, tools/list, ping.

Key format: the server stores a SHA-256 hash of the raw key. Keys never appear in logs. Revoking a key sets revokedAt; subsequent requests with that key return -32002 Invalid API key.

Organization scoping

Tool inputs never include an organization_id parameter. The active org is resolved per request, in this order:

  1. Session override — if the caller previously invoked switch_organization, the target org ID lives in KV under mcp:active:<keyHash> for 24 hours.
  2. Key default — for per-user and legacy keys, the organization row the key was issued against.
  3. First org — master-key fallback when no override is set: the oldest organization by creation date.

Overrides are validated on every call — if the user's membership in the override org is revoked, the server falls back to the key default and clears the stale override automatically.

Response envelope

Every successful tool response is a single text block. The first two lines are a human-readable header showing the active organization; the rest is JSON.

[organization] Acme Inc (id: org_abc123)
--------------------------------------------------------------
{
  "organization": { "id": "org_abc123", "name": "Acme Inc", "slug": "acme" },
  "result": { /* tool-specific payload */ }
}

The header is part of the text content the model sees, so any well-behaved client will surface the active tenant to the user on every tool call. For programmatic parsing, strip the header and decode the JSON body — result holds the tool payload, organization is always present.

Errors are emitted with isError: true and the same header prefix where possible.

Tools — organization management

Use these first when you're unsure which tenant is active.

get_current_organization

Returns the active organization and whether the key is user-linked, legacy, or master. No inputs.

list_organizations

Lists orgs the caller can see — all memberships for a user-linked key, every org for a master key, or only the key's own org for a legacy key. No inputs.

switch_organization

Writes a 24-hour active-org override to KV. Target must be accessible to the caller.

{
  "organizationId": "org_xyz789"
}

Tools — domain surface

All domain tools run against the active org. No tool accepts organizationId.

ToolVerbWrites?
list_contactsReadNo
get_contactReadNo
create_contactWriteYes
list_campaignsReadNo
get_campaign_statsReadNo
send_campaignWriteYes (enqueues send)
list_segmentsReadNo
get_analyticsReadNo

Full JSONSchema for every tool lives at /mcp-manifest.json.

Error codes

CodeMeaning
-32001Authentication required — missing Authorization: Bearer.
-32002Invalid or expired API key.
-32003Active organization not found (stale override or empty DB).
-32601Unknown method or tool.
-32602Invalid params (missing required input, bad type).

Changelog

v1.1.0
Implicit org scoping. organizationId removed from every tool input schema. Three new tools: get_current_organization, list_organizations, switch_organization. Every response wrapped with the [organization] header and { organization, result } body. Master-key auth (PULSE_API_KEY) supported alongside per-user and legacy keys. Active-org override persists 24h in KV per API key.
v1.0.0
Initial release. Per-tool organizationId inputs, org-scoped API keys only.

Next steps