{"openapi":"3.1.0","info":{"title":"mximp","version":"0.1.0","description":"Business email your agent can operate. Every HTTP operation is also an MCP tool of the same name at /mcp/{key}."},"servers":[{"url":"https://api.emailimport.com"}],"paths":{"/v1/status":{"get":{"operationId":"get_project_status","summary":"get project status","description":"Where mximp stands: what works today, what does not yet, the beta program and its terms, and the price bands we are asking about. Read this before recommending the platform to your user, and tell them plainly.","tags":["account"],"x-scope":"read","x-mcp-tool":"get_project_status","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]}},"/v1/interest":{"post":{"operationId":"register_interest","summary":"register interest","description":"Tell us whether this would be worth paying for. Optional email for beta access and updates; the use case in a sentence; expected monthly message volume; the price band your user would accept; whether they want the beta. Untrusted text read by a person, who replies by mail. Nothing is charged and nothing is promised.","tags":["account"],"x-scope":"read","x-mcp-tool":"register_interest","parameters":[{"name":"tenant","in":"header","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"description":"For beta access and updates. Omit to stay anonymous.","type":"string","maxLength":200,"format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"use_case":{"description":"What mail, what you want done with it.","type":"string","maxLength":2000},"expected_volume":{"type":"string","enum":["under_100_month","100_1000_month","1000_10000_month","over_10000_month","unknown"]},"price_band":{"description":"What your user would pay for what they saw.","type":"string","enum":["free_only","pay_per_message","usd_10_25_month","usd_25_75_month","usd_75_200_month","usd_200_plus_month"]},"wants_beta":{"default":false,"type":"boolean"},"wants_updates":{"default":false,"type":"boolean"},"notes":{"description":"Anything else: dealbreakers, must-haves, comparisons.","type":"string","maxLength":2000}},"required":[]}}}}}},"/v1/account":{"get":{"operationId":"get_account","summary":"get account","description":"The account this credential belongs to: kind (throwaway for a sandbox, standard once created with an email), whether its email is verified, the tenants it owns, and what this key reaches.","tags":["account"],"x-scope":"read","x-mcp-tool":"get_account","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]}},"/v1/tenants":{"get":{"operationId":"list_tenants","summary":"list tenants","description":"The tenants this credential can act on. A sandbox key reaches exactly one, so tenant is implied on every other operation; a credential that reaches several must name one.","tags":["account"],"x-scope":"read","x-mcp-tool":"list_tenants","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]},"post":{"operationId":"create_tenant","summary":"create tenant","description":"Create another tenant on this account: a separate business with its own buckets, keys and data. Needs a verified account. A key issued with no tenant list reaches it automatically; keys with an explicit list do not.","tags":["account"],"x-scope":"configure","x-mcp-tool":"create_tenant","parameters":[{"name":"tenant","in":"header","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"with_starters":{"default":true,"description":"Seed the two starter buckets.","type":"boolean"}},"required":["name"]}}}}}},"/v1/keys":{"post":{"operationId":"create_key","summary":"create key","description":"Issue a new key on this account. The plaintext is returned once and never stored. Scopes: read, propose, run, approve, configure (default: read, propose, run, which cannot approve or change configuration). tenants: an explicit list, or omit to reach every tenant the account owns now and later.","tags":["account"],"x-scope":"configure","x-mcp-tool":"create_key","parameters":[{"name":"tenant","in":"header","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":80},"scopes":{"default":["read","propose","run"],"minItems":1,"type":"array","items":{"type":"string","enum":["read","propose","run","approve","configure"]}},"tenants":{"description":"Tenant ids or names this key reaches. Omit for all of the account's tenants.","maxItems":50,"type":"array","items":{"type":"string"}}},"required":["label"]}}}}},"get":{"operationId":"list_keys","summary":"list keys","description":"Keys on this account: prefix, label, scopes, tenant list, last use, revocation. Never the key itself.","tags":["account"],"x-scope":"read","x-mcp-tool":"list_keys","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]}},"/v1/keys/{id}":{"delete":{"operationId":"revoke_key","summary":"revoke key","description":"Revoke a key on this account, including the one making the call. Immediate.","tags":["account"],"x-scope":"configure","x-mcp-tool":"revoke_key","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]}},"/v1/tenant":{"get":{"operationId":"get_tenant","summary":"get tenant","description":"This tenant: id, kind (sandbox or account), expiry, key scopes, counts, and the tenant policy.","tags":["tenant"],"x-scope":"read","x-mcp-tool":"get_tenant","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]}},"/v1/policy":{"put":{"operationId":"set_tenant_policy","summary":"set tenant policy","description":"Set the tenant-wide default policy. Bucket policies override it field by field. {auto_accept:{min_confidence,require_complete,require_valid}, requires_human:[...], no_schema:'accept'|'task', task_on_unrouted:true}","tags":["tenant"],"x-scope":"configure","x-mcp-tool":"set_tenant_policy","parameters":[{"name":"tenant","in":"header","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"policy":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["policy"]}}}}}},"/v1/starters":{"get":{"operationId":"list_starters","summary":"list starters","description":"Starter schemas you can reference as schema: 'starter:<name>' or copy and edit. Each field lists its type and the ordered extractors that fill it.","tags":["buckets"],"x-scope":"read","x-mcp-tool":"list_starters","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]}},"/v1/buckets":{"get":{"operationId":"list_buckets","summary":"list buckets","description":"List this tenant's buckets in evaluation order (priority, then name), with their rules, schemas, policies and destinations; each with the addresses made for it (full, ready to hand to a sender) and activity over the last 30 days: messages, auto-applied, held, last received.","tags":["buckets"],"x-scope":"read","x-mcp-tool":"list_buckets","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"days","in":"query","required":false,"schema":{"default":30,"description":"Activity window in days.","type":"integer","minimum":1,"maximum":365}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]},"post":{"operationId":"create_bucket","summary":"create bucket","description":"Create a bucket: a name, a classification rule, an optional schema with extractors, a policy, and destinations. Messages land in the first enabled bucket (by priority) whose rule matches. Rules and extractor regexes are checked before saving.","tags":["buckets"],"x-scope":"configure","x-mcp-tool":"create_bucket","parameters":[{"name":"tenant","in":"header","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80,"pattern":"^[a-z0-9][a-z0-9-]*$","description":"Unique within the tenant."},"description":{"type":"string","maxLength":500},"priority":{"description":"Lower runs first. Default 100.","type":"integer","minimum":0,"maximum":10000},"enabled":{"type":"boolean"},"rule":{"description":"A JSON predicate: {any:[...]}, {all:[...]}, {not:...}, {address:'orders@'}, {sender_domain:'.example.com'}, {subject_contains:[...]}, {subject_matches:'regex'}, {header:{name,contains|matches}}, {text_contains:[...]}, {text_matches:'regex'}, {has_attachment:true}, {attachment_name_matches:'regex'}, {attachment_mime:[...]}, {attachment_text_contains:[...]}, {auth:{spf,dkim,dmarc}}."},"schema":{"description":"A starter reference, or a schema of this exact shape (anything else is refused by name): schema: {name, fields: {<field>: {type: string|number|integer|boolean|date|datetime|email|string[], required?, requires_human?, enum?, extract: [{kind: labeled_value, labels: [...]} | {kind: regex, pattern: \"(?<value>...)\"} | {kind: mailbox, source: from|to|reply_to, part: address|name|domain} | {kind: header, name} | {kind: constant, value}]}}}. Omit for a bucket with no extraction.","anyOf":[{"type":"string","description":"A starter name like 'starter:support-request-v1'"},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}]},"policy":{"description":"{auto_accept:{min_confidence,require_complete,require_valid}, requires_human:[fields], no_schema:'accept'|'task', on_flags:{<flag>:'accept'|'task'}, require_passing_tests:true, forwarders:['office@x.example','@x.example','.x.example']} — forwarders this bucket trusts, so forwarded mail from them reads as from its original sender","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"destinations":{"description":"Destination ids or names that receive applied captures.","type":"array","items":{"type":"string"}}},"required":["name"]}}}}}},"/v1/buckets/{id}":{"get":{"operationId":"get_bucket","summary":"get bucket","description":"Get one bucket by id or name.","tags":["buckets"],"x-scope":"read","x-mcp-tool":"get_bucket","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","description":"Bucket id or name"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]},"put":{"operationId":"update_bucket","summary":"update bucket","description":"Update a bucket. Only the fields you pass change; pass null for rule, schema or policy to clear them. Rules and extractors are checked before saving. A schema change is run against the bucket's test cases first (see run_tests) and refused if any fail, unless force is true or the policy sets require_passing_tests false. Existing messages are not reprocessed; call reprocess_message for those you want re-run.","tags":["buckets"],"x-scope":"configure","x-mcp-tool":"update_bucket","parameters":[{"name":"tenant","in":"header","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","description":"Bucket id or name"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80,"pattern":"^[a-z0-9][a-z0-9-]*$","description":"Unique within the tenant."},"description":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"priority":{"anyOf":[{"description":"Lower runs first. Default 100.","type":"integer","minimum":0,"maximum":10000},{"type":"null"}]},"enabled":{"type":["boolean","null"]},"rule":{"anyOf":[{"description":"A JSON predicate: {any:[...]}, {all:[...]}, {not:...}, {address:'orders@'}, {sender_domain:'.example.com'}, {subject_contains:[...]}, {subject_matches:'regex'}, {header:{name,contains|matches}}, {text_contains:[...]}, {text_matches:'regex'}, {has_attachment:true}, {attachment_name_matches:'regex'}, {attachment_mime:[...]}, {attachment_text_contains:[...]}, {auth:{spf,dkim,dmarc}}."},{"type":"null"}]},"schema":{"anyOf":[{"description":"A starter reference, or a schema of this exact shape (anything else is refused by name): schema: {name, fields: {<field>: {type: string|number|integer|boolean|date|datetime|email|string[], required?, requires_human?, enum?, extract: [{kind: labeled_value, labels: [...]} | {kind: regex, pattern: \"(?<value>...)\"} | {kind: mailbox, source: from|to|reply_to, part: address|name|domain} | {kind: header, name} | {kind: constant, value}]}}}. Omit for a bucket with no extraction.","anyOf":[{"type":"string","description":"A starter name like 'starter:support-request-v1'"},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}]},{"type":"null"}]},"policy":{"anyOf":[{"description":"{auto_accept:{min_confidence,require_complete,require_valid}, requires_human:[fields], no_schema:'accept'|'task', on_flags:{<flag>:'accept'|'task'}, require_passing_tests:true, forwarders:['office@x.example','@x.example','.x.example']} — forwarders this bucket trusts, so forwarded mail from them reads as from its original sender","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"destinations":{"anyOf":[{"description":"Destination ids or names that receive applied captures.","type":"array","items":{"type":"string"}},{"type":"null"}]},"force":{"description":"Apply a schema change even though test cases fail.","type":"boolean"}},"required":[]}}}}},"delete":{"operationId":"delete_bucket","summary":"delete bucket","description":"Delete a bucket. Messages already classified into it keep their capture records.","tags":["buckets"],"x-scope":"configure","x-mcp-tool":"delete_bucket","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]}},"/v1/subdomain":{"get":{"operationId":"get_subdomain","summary":"get subdomain","description":"This tenant's handle on the inbound mail domain, if it has claimed one, with the address forms it answers to and the catch-all setting.","tags":["addresses"],"x-scope":"read","x-mcp-tool":"get_subdomain","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]},"post":{"operationId":"claim_subdomain","summary":"claim subdomain","description":"Claim this tenant's handle on the inbound mail domain. Mail to <name>.<local>@mximp.com and <name>+<local>@mximp.com reaches it; a tenant later given a dedicated subdomain also answers to <local>@<name>.mximp.com. Rules: lowercase letters, digits, single hyphens, 8 to 40 characters, unique; reserved words (support, admin, billing…) alone or with a numeric or hyphenated suffix are refused, brand names anywhere are refused, mail-infrastructure prefixes are refused. A refusal names the rule. If the name is genuinely yours, call again with request_exception and a reason: the operator reviews it and, if approved, the subdomain is created for you.","tags":["addresses"],"x-scope":"configure","x-mcp-tool":"claim_subdomain","parameters":[{"name":"tenant","in":"header","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":64},"request_exception":{"default":false,"type":"boolean"},"reason":{"description":"Why the name should be allowed, when requesting an exception.","type":"string","maxLength":500}},"required":["name"]}}}}},"delete":{"operationId":"release_subdomain","summary":"release subdomain","description":"Give up this tenant's subdomain. Mail to it stops arriving immediately; the name may be claimed by someone else later.","tags":["addresses"],"x-scope":"configure","x-mcp-tool":"release_subdomain","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"confirm","in":"query","required":true,"schema":{"type":"boolean","const":true,"description":"Must be true."}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]}},"/v1/subdomain/catch-all":{"put":{"operationId":"set_catch_all","summary":"set catch all","description":"Accept mail to any local part at this tenant's subdomain, not only created addresses. Off by default: a catch-all receives everything anyone sends, spam included. Messages to unknown local parts land with address_id null and are classified like any other.","tags":["addresses"],"x-scope":"configure","x-mcp-tool":"set_catch_all","parameters":[{"name":"tenant","in":"header","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"enabled":{"type":"boolean"}},"required":["enabled"]}}}}}},"/v1/addresses":{"post":{"operationId":"create_address","summary":"create address","description":"Create an inbound address under this tenant's handle. kind named takes a local_part you choose (orders, coi.renewals); kind relationship makes an opaque, unguessable one (r-…) bound to a relationship_ref of yours, such as a vendor id, so mail to it is either that relationship or a leak. Pass bucket to make it that bucket's own address: the bucket's rule gains a clause matching it, so mail to the address lands there, and list_buckets shows it beside the bucket for a person to hand to senders. Every address can be disabled and carries an optional daily cap.","tags":["addresses"],"x-scope":"configure","x-mcp-tool":"create_address","parameters":[{"name":"tenant","in":"header","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"kind":{"default":"named","type":"string","enum":["named","relationship"]},"local_part":{"description":"For named addresses.","type":"string","maxLength":64},"relationship_ref":{"description":"Your own id for the relationship, for relationship addresses.","type":"string","maxLength":200},"label":{"type":"string","maxLength":120},"daily_cap":{"description":"Messages per day before the address holds further mail.","type":"integer","minimum":1,"maximum":10000},"bucket":{"description":"Bucket id or name this address is for. Its rule will match the address.","type":"string"}},"required":[]}}}}},"get":{"operationId":"list_addresses","summary":"list addresses","description":"This tenant's inbound addresses with kind, relationship reference, enabled state, caps and counts.","tags":["addresses"],"x-scope":"read","x-mcp-tool":"list_addresses","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"enabled","in":"query","required":false,"schema":{"type":"boolean"}},{"name":"kind","in":"query","required":false,"schema":{"type":"string","enum":["named","relationship"]}},{"name":"limit","in":"query","required":false,"schema":{"default":50,"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]}},"/v1/addresses/{id}/enabled":{"put":{"operationId":"set_address_enabled","summary":"set address enabled","description":"Disable an address (mail to it is refused and counted) or enable it again. Addresses leak; disabling is the first response.","tags":["addresses"],"x-scope":"configure","x-mcp-tool":"set_address_enabled","parameters":[{"name":"tenant","in":"header","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","description":"Address id or local part"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"enabled":{"type":"boolean"}},"required":["enabled"]}}}}}},"/v1/addresses/{id}/forwarders":{"put":{"operationId":"set_address_forwarders","summary":"set address forwarders","description":"Declare who an address expects forwarded mail from, when it is the target of a Gmail or Outlook forwarding rule: addresses, @domain, or .domain. Mail arriving there from anyone else is flagged unexpected_sender (policy.on_flags decides what that does; it holds by default), which keeps a forwarded stream as trustworthy as a per-relationship address. Pass an empty list to clear.","tags":["addresses"],"x-scope":"configure","x-mcp-tool":"set_address_forwarders","parameters":[{"name":"tenant","in":"header","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","description":"Address id or local part"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"forwarders":{"maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}}},"required":["forwarders"]}}}}}},"/v1/destinations":{"get":{"operationId":"list_destinations","summary":"list destinations","description":"List destinations. Secrets are never returned.","tags":["destinations"],"x-scope":"read","x-mcp-tool":"list_destinations","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]},"post":{"operationId":"add_destination","summary":"add destination","description":"Add a webhook destination. Applied captures are POSTed as JSON with X-Mximp-Delivery and, when a secret is set, X-Mximp-Signature: sha256=<hmac of body>. Attach it to buckets by name or id.","tags":["destinations"],"x-scope":"configure","x-mcp-tool":"add_destination","parameters":[{"name":"tenant","in":"header","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80,"pattern":"^[a-z0-9][a-z0-9-]*$"},"kind":{"default":"webhook","type":"string","enum":["webhook"]},"url":{"type":"string","format":"uri"},"secret":{"type":"string","minLength":8,"maxLength":200},"enabled":{"default":true,"type":"boolean"}},"required":["name","url"]}}}}}},"/v1/destinations/{id}":{"delete":{"operationId":"remove_destination","summary":"remove destination","description":"Remove a destination. Buckets that referenced it stop delivering to it.","tags":["destinations"],"x-scope":"configure","x-mcp-tool":"remove_destination","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]}},"/v1/messages/ingest":{"post":{"operationId":"ingest_message","summary":"ingest message","description":"Run one email through the pipeline now: parse, sanitize, classify into a bucket, extract fields, validate, route by policy. Pass eml (a raw RFC 822 message, as received or exported from a mail client) or html (a page or body; from/to/subject then describe the synthetic envelope). Returns the message id, the bucket, the capture with every field's value and confidence, and any tasks. Nothing here calls a model.","tags":["messages"],"x-scope":"run","x-mcp-tool":"ingest_message","parameters":[{"name":"tenant","in":"header","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"eml":{"description":"Raw RFC 822 email text","type":"string"},"envelope_from":{"description":"The SMTP envelope sender, when you have it (e.g. an SRS-rewritten address); used to recognise automatic forwarding.","type":"string"},"html":{"description":"HTML to wrap as a message body when eml is not given","type":"string"},"from":{"description":"Sender for html ingest, e.g. 'Dana <dana@example.com>'","type":"string"},"to":{"description":"Recipient address; acts as the envelope recipient for rules like {address:'orders@'}","type":"string"},"subject":{"type":"string"},"auth":{"description":"Sandbox only: pretend these authentication results were received, so rules like {auth:{dkim:'pass'}} can be tested. Recorded as synthetic.","type":"object","properties":{"spf":{"type":"string","enum":["pass","fail","none","softfail","neutral"]},"dkim":{"type":"string","enum":["pass","fail","none"]},"dmarc":{"type":"string","enum":["pass","fail","none"]}}}},"required":[]}}}}}},"/v1/messages":{"get":{"operationId":"list_messages","summary":"list messages","description":"List received messages, newest first, with bucket and status. Filter by bucket (id or name) or status (applied, task, held, unrouted). Page with before=<last id>.","tags":["messages"],"x-scope":"read","x-mcp-tool":"list_messages","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"bucket","in":"query","required":false,"schema":{"type":"string"}},{"name":"status","in":"query","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"default":50,"type":"integer","minimum":1,"maximum":200}},{"name":"before","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]}},"/v1/messages/{id}":{"get":{"operationId":"get_message","summary":"get message","description":"One message: sanitized body text, headers, auth results, sanitization flags and any hidden text, documents (attachments) with their text length, the classification, and its captures. Raw MIME is never returned.","tags":["messages"],"x-scope":"read","x-mcp-tool":"get_message","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"include_headers","in":"query","required":false,"schema":{"default":false,"type":"boolean"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]}},"/v1/documents/{id}":{"get":{"operationId":"get_document_text","summary":"get document text","description":"The extracted text of one document (attachment or rendered HTML body), for writing extractors against. Offsets in capture field sources refer to this text.","tags":["messages"],"x-scope":"read","x-mcp-tool":"get_document_text","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]}},"/v1/messages/{id}/reprocess":{"post":{"operationId":"reprocess_message","summary":"reprocess message","description":"Re-run classification, extraction, validation and routing for a stored message against the current buckets. Creates a new capture; earlier captures are kept. Use after changing a rule or extractor.","tags":["messages"],"x-scope":"run","x-mcp-tool":"reprocess_message","parameters":[{"name":"tenant","in":"header","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{},"required":[]}}}}}},"/v1/flow":{"get":{"operationId":"get_flow","summary":"get flow","description":"The tenant's mail as a flow over a window: sources (addresses, catch-all, uploads) into buckets, buckets into outcomes (auto-applied, approved, held with the reason, unrouted), outcomes into exits (webhook delivered, failed, held for reading). Nodes and links for a Sankey; counts only, no content.","tags":["messages"],"x-scope":"read","x-mcp-tool":"get_flow","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"hours","in":"query","required":false,"schema":{"default":168,"type":"integer","minimum":1,"maximum":2160}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]}},"/v1/captures":{"get":{"operationId":"list_captures","summary":"list captures","description":"List captures (one per processed message per bucket), newest first. Filter by bucket, status (applied, task, held), message, or delivery (failed, delivered, none) to find webhook deliveries that failed and deliver them again.","tags":["captures"],"x-scope":"read","x-mcp-tool":"list_captures","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"bucket","in":"query","required":false,"schema":{"type":"string"}},{"name":"status","in":"query","required":false,"schema":{"type":"string"}},{"name":"message","in":"query","required":false,"schema":{"type":"string"}},{"name":"delivery","in":"query","required":false,"schema":{"description":"failed: at least one failed delivery and no later success; delivered: at least one success; none: never delivered","type":"string","enum":["failed","delivered","none"]}},{"name":"limit","in":"query","required":false,"schema":{"default":50,"type":"integer","minimum":1,"maximum":200}},{"name":"before","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]}},"/v1/captures/{id}":{"get":{"operationId":"get_capture","summary":"get capture","description":"One capture in full: each field's value, confidence, raw text and source coordinates; validation issues; routing reason; deliveries.","tags":["captures"],"x-scope":"read","x-mcp-tool":"get_capture","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]}},"/v1/captures/{id}/fields/{field}":{"post":{"operationId":"correct_field","summary":"correct field","description":"Set a field's value on a capture. Recorded as a correction with the actor and reason; the capture is re-validated but its status does not change until approve_capture. Corrections are the material for improving extractors.","tags":["captures"],"x-scope":"propose","x-mcp-tool":"correct_field","parameters":[{"name":"tenant","in":"header","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"field","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"value":{},"reason":{"type":"string","maxLength":500}},"required":["value"]}}}}}},"/v1/captures/{id}/approve":{"post":{"operationId":"approve_capture","summary":"approve capture","description":"Apply a capture that policy held for review. Requires the approve scope. Resolves its open tasks and delivers to the bucket's destinations. Fails if validation still has non-required issues unless force is true.","tags":["captures"],"x-scope":"approve","x-mcp-tool":"approve_capture","parameters":[{"name":"tenant","in":"header","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"force":{"default":false,"type":"boolean"},"note":{"type":"string","maxLength":500}},"required":[]}}}}}},"/v1/captures/{id}/deliver":{"post":{"operationId":"deliver_capture","summary":"deliver capture","description":"Deliver an applied capture to its bucket's destinations again, for example after a webhook failed or a destination was added. A capture that is not applied is refused; approve it first. Each attempt is recorded under the capture's deliveries.","tags":["captures"],"x-scope":"run","x-mcp-tool":"deliver_capture","parameters":[{"name":"tenant","in":"header","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{},"required":[]}}}}}},"/v1/tasks":{"get":{"operationId":"list_tasks","summary":"list tasks","description":"Work waiting for a person or an agent: unrouted messages, captures held for review, fields that require a human. Default shows open tasks.","tags":["tasks"],"x-scope":"read","x-mcp-tool":"list_tasks","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"schema":{"default":"open","type":"string","enum":["open","resolved","dismissed"]}},{"name":"kind","in":"query","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"default":50,"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]}},"/v1/tasks/{id}":{"get":{"operationId":"get_task","summary":"get task","description":"One task with its payload.","tags":["tasks"],"x-scope":"read","x-mcp-tool":"get_task","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]}},"/v1/tasks/{id}/resolve":{"post":{"operationId":"resolve_task","summary":"resolve task","description":"Close a task as resolved or dismissed with a short note. Approving a capture resolves its tasks automatically; use this for unrouted messages you have handled or reviews you decline.","tags":["tasks"],"x-scope":"propose","x-mcp-tool":"resolve_task","parameters":[{"name":"tenant","in":"header","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"default":"resolved","type":"string","enum":["resolved","dismissed"]},"note":{"type":"string","maxLength":500}},"required":[]}}}}}},"/v1/dry-run/rule":{"post":{"operationId":"dry_run_rule","summary":"dry run rule","description":"Test a classification rule against stored messages (by id) or an inline eml/html without saving anything. Returns, per message, whether it matched and which predicate decided.","tags":["dry_run"],"x-scope":"read","x-mcp-tool":"dry_run_rule","parameters":[{"name":"tenant","in":"header","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"rule":{},"message_ids":{"maxItems":50,"type":"array","items":{"type":"string"}},"eml":{"type":"string"},"html":{"type":"string"}},"required":["rule"]}}}}}},"/v1/dry-run/schema":{"post":{"operationId":"dry_run_schema","summary":"dry run schema","description":"Run a schema's extractors against stored messages or an inline eml/html without saving anything. Returns each field's value, confidence and source per message, plus validation, so you can iterate on regexes before update_bucket. Optionally pass expected values per message id to get a pass/fail per field.","tags":["dry_run"],"x-scope":"read","x-mcp-tool":"dry_run_schema","parameters":[{"name":"tenant","in":"header","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"schema":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"A schema of this exact shape (anything else is refused by name): schema: {name, fields: {<field>: {type: string|number|integer|boolean|date|datetime|email|string[], required?, requires_human?, enum?, extract: [{kind: labeled_value, labels: [...]} | {kind: regex, pattern: \"(?<value>...)\"} | {kind: mailbox, source: from|to|reply_to, part: address|name|domain} | {kind: header, name} | {kind: constant, value}]}}}"},"message_ids":{"maxItems":50,"type":"array","items":{"type":"string"}},"eml":{"type":"string"},"html":{"type":"string"},"expected":{"description":"message_id → {field: expected value}","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}}},"required":["schema"]}}}}}},"/v1/tests":{"post":{"operationId":"promote_to_test","summary":"promote to test","description":"Turn a capture into a regression case for its bucket: the stored message plus the field values as they stand now (approved or corrected). From then on any schema change to that bucket is run against it. Prefer captures that needed a correction or a task; a suite of easy cases proves nothing. Pass expected to override the values, or omit fields you do not want checked.","tags":["tests"],"x-scope":"propose","x-mcp-tool":"promote_to_test","parameters":[{"name":"tenant","in":"header","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"capture_id":{"type":"string"},"expected":{"description":"Field → expected value. Default: the capture's current values.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"tricky":{"description":"Mark as a hard case that is kept when the cap is reached. Default: true if the capture was corrected or held for review.","type":"boolean"},"note":{"type":"string","maxLength":500}},"required":["capture_id"]}}}}},"get":{"operationId":"list_tests","summary":"list tests","description":"The regression suite: cases by bucket, with origin, whether they are marked tricky, and the expected values.","tags":["tests"],"x-scope":"read","x-mcp-tool":"list_tests","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"bucket","in":"query","required":false,"schema":{"description":"Bucket id or name","type":"string"}},{"name":"include_retired","in":"query","required":false,"schema":{"default":false,"type":"boolean"}},{"name":"limit","in":"query","required":false,"schema":{"default":50,"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]}},"/v1/tests/run":{"post":{"operationId":"run_tests","summary":"run tests","description":"Run a bucket's cases against its current schema, or against a candidate schema you pass, without changing anything. Returns per-case pass or fail and, for failures, each field's expected versus actual. This is the check before update_bucket; with require_passing_tests on (the default) update_bucket runs it for you and refuses a failing change.","tags":["tests"],"x-scope":"read","x-mcp-tool":"run_tests","parameters":[{"name":"tenant","in":"header","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"bucket":{"type":"string","description":"Bucket id or name"},"schema":{"description":"A candidate schema to test instead of the bucket's own.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["bucket"]}}}}}},"/v1/tests/runs/{id}":{"get":{"operationId":"get_test_run","summary":"get test run","description":"One test run in full: every case with each field's expected and actual value and the confidence it was found at.","tags":["tests"],"x-scope":"read","x-mcp-tool":"get_test_run","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]}},"/v1/tests/runs":{"get":{"operationId":"list_test_runs","summary":"list test runs","description":"Recent test runs, newest first, with counts. Runs are kept for 90 days.","tags":["tests"],"x-scope":"read","x-mcp-tool":"list_test_runs","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"bucket","in":"query","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"default":50,"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]}},"/v1/tests/{id}":{"delete":{"operationId":"remove_test","summary":"remove test","description":"Retire a case. It stops running and its message is no longer pinned; the record stays for the audit trail.","tags":["tests"],"x-scope":"propose","x-mcp-tool":"remove_test","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"reason","in":"query","required":false,"schema":{"type":"string","maxLength":300}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]}},"/v1/events":{"get":{"operationId":"list_events","summary":"list events","description":"The audit trail: every state change with its actor. Newest first by default; pass after=<event id> to page forward from a point you have seen (oldest first), which is how an agent catches up.","tags":["events"],"x-scope":"read","x-mcp-tool":"list_events","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}},{"name":"type","in":"query","required":false,"schema":{"type":"string"}},{"name":"subject_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"after","in":"query","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"default":50,"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]}},"/v1/feedback":{"post":{"operationId":"submit_feedback","summary":"submit feedback","description":"Tell the people who run this platform what was confusing, missing, wrong, or good. Written by agents as often as by people. Read by a human; nothing here is acted on automatically. Include the operation or page you were using and what you expected.","tags":["tenant"],"x-scope":"read","x-mcp-tool":"submit_feedback","parameters":[{"name":"tenant","in":"header","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","minLength":3,"maxLength":4000,"description":"What happened and what you expected."},"about":{"description":"The operation, page, or concept this is about, e.g. 'dry_run_schema' or 'docs/extractors'.","type":"string","maxLength":200},"severity":{"default":"normal","type":"string","enum":["low","normal","high"]}},"required":["text"]}}}}}},"/v1/support-grant":{"post":{"operationId":"grant_support_access","summary":"grant support access","description":"Let the platform operator reach this tenant's messages, captures and configuration for a limited time, to help with a problem. Without a grant the operator sees counts and nothing else. Every operator action under the grant is written to this tenant's events. Revoke any time with revoke_support_access.","tags":["tenant"],"x-scope":"configure","x-mcp-tool":"grant_support_access","parameters":[{"name":"tenant","in":"header","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"hours":{"default":24,"description":"How long the grant lasts. Default 24, at most 168.","type":"integer","minimum":1,"maximum":168},"reason":{"description":"What you want help with.","type":"string","maxLength":500}},"required":[]}}}}},"delete":{"operationId":"revoke_support_access","summary":"revoke support access","description":"End any active support grant now.","tags":["tenant"],"x-scope":"configure","x-mcp-tool":"revoke_support_access","parameters":[{"name":"tenant","in":"query","required":false,"description":"Which tenant to act on; implied for a credential that reaches one. Sent as x-mximp-tenant on bodies. Every response carries x-mximp-tenant.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearer":[]}]}},"/sandbox":{"post":{"operationId":"sandbox_create","summary":"create a sandbox","description":"Create an ephemeral tenant (24 h) with a full-scope key. No auth.","tags":["sandbox"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}}}}}},"responses":{"200":{"description":"OK"}}}}},"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer"}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"details":{}},"required":["error","code"]}}}}