{"openapi":"3.1.0","info":{"title":"varve","summary":"Memory for team assistants. OpenAI-compatible.","description":"Authenticate with `Authorization: Bearer vrv_live_…`.\n\nKeys may be scoped to any subset of `read`, `write`, `chat` and `erase`; a key with no scopes set is unrestricted. Using an endpoint outside a key's scopes returns 403, not 404 — the scope check runs before the lookup, so a narrow key cannot probe for what exists.","version":"1.0.0"},"paths":{"/v1/chat/completions":{"post":{"summary":"Chat Completions","operationId":"chat_completions_v1_chat_completions_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["messages"],"properties":{"model":{"type":"string","description":"Any model your provider key can reach. Defaults to the tenant's configured model."},"messages":{"type":"array","description":"OpenAI message list.","items":{"type":"object","required":["role","content"],"properties":{"role":{"type":"string","enum":["system","user","assistant"]},"content":{"type":"string"}}}},"user":{"type":"string","description":"Who the memory belongs to. Without it you get shared org knowledge only and never anyone's personal facts -- the failure mode is empty, not somebody else's data."},"session":{"type":"string","description":"Groups turns into one conversation."},"stream":{"type":"boolean","default":false,"description":"NOT SUPPORTED. Accepted and ignored: the response is always one complete JSON body. A generated client that sets this gets a buffered answer and no error, so it is documented here rather than only in the prose on /docs."},"temperature":{"type":"number"},"max_tokens":{"type":"integer"}}}}}}}},"/v1/memory/facts":{"get":{"summary":"List Facts","operationId":"list_facts_v1_memory_facts_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/memory/search":{"get":{"summary":"Memory Search","description":"Retrieval on its own, with no model call and no prompt assembly.\n\nThe proxy is the right DEFAULT -- cache optimisation needs control of how\nthe prompt is built -- but it is the wrong only option, because it puts us\nin the customer's request path as a hard dependency and shuts out anyone\nwho cannot re-point their stack. This is the same cascade the proxy runs,\nreturning what it found instead of sending it to a model.\n\nCosts one embedding and no tokens. Nothing here spends the customer's\nprovider budget, which is why it needs `read` rather than `chat`.","operationId":"memory_search_v1_memory_search_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","title":"Q"}},{"name":"subject","in":"query","required":false,"schema":{"type":"string","title":"Subject"}},{"name":"k","in":"query","required":false,"schema":{"type":"integer","default":6,"title":"K"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/memory/turns":{"get":{"summary":"Memory Turns","description":"The episodic log, decrypted for the tenant that owns it.\n\nFacts are derived and rebuildable; this is the record they were derived\nFROM, and a customer who cannot read it is trusting us about the one thing\nwe tell them not to trust anyone about. Keyset paged on id, like the audit\ntrail, because the log only grows.","operationId":"memory_turns_v1_memory_turns_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"subject","in":"query","required":false,"schema":{"type":"string","title":"Subject"}},{"name":"before","in":"query","required":false,"schema":{"type":"integer","title":"Before"}},{"name":"session","in":"query","required":false,"schema":{"type":"string","title":"Session"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/ingest/{source_id}":{"post":{"summary":"Ingest","description":"One URL a customer POSTs a turn to, from anything that speaks HTTP.\n\nEvery other source needed an adapter written here first, which made us the\nqueue that every integration waits in. This removes that: the memory does\nnot care where a sentence came from, only the adapters did.\n\nAuthenticated by signature rather than by API key, so a customer's server\ncan post without embedding a bearer token that also grants read and spend.\nThe caller signs `{timestamp}.{raw body}` with the source secret:\n\n    X-Varve-Timestamp: 1787500000\n    X-Varve-Signature: v1=<hex hmac-sha256>\n\nTwo things defend it. The signature proves origin; the timestamp bounds how\nlong a captured request stays valid.\n\nA third -- remembering signatures to reject replays -- was built and then\nremoved, because it was defending nothing. This write is idempotent: a turn\nis keyed on (tenant, provider, provider_msg) and re-asserting one does\nnothing. So a replayed request cannot create, alter or delete anything, and\nthe only thing the replay table achieved was turning an honest at-least-once\nretry into a 409 whenever it arrived in the same second as the original --\nidentical body plus identical timestamp means an identical signature, and\nnothing can tell those two cases apart. Idempotency was already the real\ncontrol; the table was ceremony on top of it.","operationId":"ingest_v1_ingest__source_id__post","parameters":[{"name":"source_id","in":"path","required":true,"schema":{"type":"string","title":"Source Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["external_id","text"],"properties":{"external_id":{"type":"string","description":"Who said it, in your own id space."},"text":{"type":"string","description":"What they said, verbatim."},"at":{"type":"string","format":"date-time","description":"When. Defaults to now."},"session":{"type":"string","description":"Which conversation. Defaults to 'webhook'."},"thread":{"type":"string","description":"Parent message id, if a reply."},"id":{"type":"string","description":"Your id for this message. Redelivering the same id is a no-op rather than a duplicate."},"role":{"type":"string","enum":["user","assistant"],"default":"user"},"is_bot":{"type":"boolean","default":false},"display_name":{"type":"string"}}}}}}}},"/v1/documents":{"post":{"summary":"Upload Document","description":"Give a new tenant something to know on day one.\n\nA customer connects Slack and the assistant knows nothing until people\nhappen to say the right things for a week -- while the handbook that\nanswers most of it is already written down. This is that path.\n\nFacts extracted here are ORG scope, with no subject. A handbook is not\nsomething a person told us about themselves, and attributing it to whoever\nuploaded it would put the company's deploy window in one employee's\npersonal memory and nobody else's.","operationId":"upload_document_v1_documents_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title","text"],"properties":{"title":{"type":"string"},"text":{"type":"string","description":"Plain text. Chunked here."},"source":{"type":"string","description":"Where it came from."},"uploaded_by":{"type":"string"}}}}}}},"get":{"summary":"List Documents","operationId":"list_documents_v1_documents_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/documents/{doc_id}":{"get":{"summary":"Read Document","description":"The text back, decrypted. What we stored has to be readable by the\ncustomer that stored it, or 'you can see what we remember' is a slogan.","operationId":"read_document_v1_documents__doc_id__get","parameters":[{"name":"doc_id","in":"path","required":true,"schema":{"type":"string","title":"Doc Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"Delete Document","description":"Removing a document removes what it taught us.\n\nOtherwise deleting an out-of-date handbook leaves the assistant still\nconfidently answering from it, which is worse than never having uploaded\nit -- the customer believes they have fixed something and has not.","operationId":"delete_document_v1_documents__doc_id__delete","parameters":[{"name":"doc_id","in":"path","required":true,"schema":{"type":"string","title":"Doc Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/webhooks":{"post":{"summary":"Create Webhook","description":"Subscribe to changes, so other systems can be built on this memory\nrather than polling it.","operationId":"create_webhook_v1_webhooks_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url","events"],"properties":{"url":{"type":"string","description":"https endpoint to POST to."},"events":{"type":"array","items":{"type":"string"},"description":"fact.created, fact.superseded, fact.corrected, fact.retired, subject.erased, document.deleted"}}}}}}},"get":{"summary":"List Webhooks","operationId":"list_webhooks_v1_webhooks_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/webhooks/{hook_id}":{"delete":{"summary":"Delete Webhook","operationId":"delete_webhook_v1_webhooks__hook_id__delete","parameters":[{"name":"hook_id","in":"path","required":true,"schema":{"type":"string","title":"Hook Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/salience":{"get":{"summary":"Get Salience","description":"What we currently think is worth remembering, and why.\n\nExposed because it is a judgement, not a fact. A customer who disagrees\nwith our priors should be able to see them before they discover them.","operationId":"get_salience_v1_salience_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/salience/{predicate}":{"put":{"summary":"Set Salience","description":"Override a prior. Ours are a starting point, not a claim about your\nbusiness -- a veterinary practice and a devtools company should not be\nstuck with the same idea of what matters.","operationId":"set_salience_v1_salience__predicate__put","parameters":[{"name":"predicate","in":"path","required":true,"schema":{"type":"string","title":"Predicate"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["weight"],"properties":{"weight":{"type":"number","minimum":0.5,"maximum":2.0},"note":{"type":"string"}}}}}}}},"/v1/threads":{"get":{"summary":"List Threads","description":"What each conversation came to, rather than every word of it.","operationId":"list_threads_v1_threads_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"session","in":"query","required":false,"schema":{"type":"string","title":"Session"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/threads/rebuild":{"post":{"summary":"Rebuild Threads","description":"Rebuild now rather than waiting for the worker.\n\nRebuilding REPLACES a summary rather than adding one -- the row is keyed on\nthe thread, so running this repeatedly converges instead of accumulating.\nIt does not produce byte-identical prose, because a language model is not\ndeterministic, and claiming otherwise would be a promise we cannot keep.","operationId":"rebuild_threads_v1_threads_rebuild_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"session":{"type":"string"},"thread":{"type":"string"},"limit":{"type":"integer","default":10}}}}}}}},"/v1/metrics":{"get":{"summary":"Metrics","description":"Usage over time, so \"is this slower than last week\" has an answer.\n\n/v1/usage answers \"what has it cost me\", as one number covering everything.\nThat cannot show a trend, and a trend is the only way to notice a\nregression before a customer does.\n\nPercentiles come from percentile_disc over the real rows rather than from\nan average. A mean latency hides exactly the tail that people complain\nabout -- ten fast calls and one ten-second call average to something that\nlooks fine and satisfies nobody.","operationId":"metrics_v1_metrics_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":7,"title":"Days"}},{"name":"bucket","in":"query","required":false,"schema":{"type":"string","default":"day","title":"Bucket"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/usage":{"get":{"summary":"Usage","operationId":"usage_v1_usage_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/memory/timeline":{"get":{"summary":"Timeline","description":"Current beliefs plus the supersession chain. This is the view that most\nmemory products cannot render, because they overwrite instead of superseding.\n\n`as_of` answers the question the whole design exists for and that nothing\ncould actually ask until now: what did we believe on a given day. The site\nhas been saying \"you can still ask what was true in March\" while every\nretrieval path filtered on is_current, so March was visible in a list and\nunqueryable everywhere else. The columns were always here -- valid_from\nand valid_to are set on supersession -- so the query is one predicate:\na fact was true at T if it had started by T and had not yet been retired.\n\nAccepts a date or a full timestamp. A fact with valid_to exactly at T is\nalready gone at T: the boundary belongs to its replacement, or two\nversions of the same predicate would both be true for an instant.","operationId":"timeline_v1_memory_timeline_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":200,"title":"Limit"}},{"name":"subject","in":"query","required":false,"schema":{"type":"string","title":"Subject"}},{"name":"as_of","in":"query","required":false,"schema":{"type":"string","title":"As Of"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/memory/fact/{fact_id}/correct":{"post":{"summary":"Correct","description":"A person replaces a stored fact with the right one.\n\nCorrections are sticky: extraction may add facts afterwards but may not\nreverse this one. A contradicting extraction is recorded as a conflict for\na human to settle instead of silently winning.","operationId":"correct_v1_memory_fact__fact_id__correct_post","parameters":[{"name":"fact_id","in":"path","required":true,"schema":{"type":"string","title":"Fact Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"actor":{"type":"string","description":"who is making the change"},"object":{"type":"string","description":"the correct value"},"fact_text":{"type":"string"},"reason":{"type":"string"}},"required":["actor"]}}}}}},"/v1/memory/fact/{fact_id}/retire":{"post":{"summary":"Retire","description":"'Forget where I work', with nothing to put in its place.\n\nDistinct from a correction, and distinct from erasure: the row stays\nreadable as history with no replacement, which is the shape supersession\ncould never express.","operationId":"retire_v1_memory_fact__fact_id__retire_post","parameters":[{"name":"fact_id","in":"path","required":true,"schema":{"type":"string","title":"Fact Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"actor":{"type":"string"},"reason":{"type":"string"}},"required":["actor"]}}}}}},"/v1/memory/conflicts":{"get":{"summary":"Conflicts","description":"Disagreements the system refused to settle on its own.\n\nEvery row here is a place where extraction wanted to overwrite something a\nperson set. Surfacing them is the honest version of \"automatic correction\":\ndetection can be automatic, deciding who is right cannot.","operationId":"conflicts_v1_memory_conflicts_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/memory/conflict/{conflict_id}/resolve":{"post":{"summary":"Resolve Conflict","description":"Settle a disagreement the system refused to settle on its own.\n\nTwo choices and no third: keep what we hold, or take what was proposed.\nThere is deliberately no \"decide for me\" -- picking between two sources\nwith no new evidence is guessing, and this whole mechanism exists because\nguessing is what we are trying to stop.","operationId":"resolve_conflict_v1_memory_conflict__conflict_id__resolve_post","parameters":[{"name":"conflict_id","in":"path","required":true,"schema":{"type":"integer","title":"Conflict Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"actor":{"type":"string"},"choice":{"type":"string","enum":["held","proposed"]}},"required":["actor","choice"]}}}}}},"/v1/memory/audit":{"get":{"summary":"Memory Audit","description":"The record of every change, exposed to the customer that owns it.\n\nA product whose pitch is \"you can see what we remember\" that hides the log\nof what changed is asking to be taken on trust for the one thing it claims\nnot to need trust for. This is a read over data already stored: no new\nplumbing, and RLS scopes it to the caller's tenant the same as everything\nelse.\n\nKeyset pagination on id rather than OFFSET -- the trail only grows, and\nOFFSET would re-read and re-skip every row before the page on every page.","operationId":"memory_audit_v1_memory_audit_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"subject","in":"query","required":false,"schema":{"type":"string","title":"Subject"}},{"name":"before","in":"query","required":false,"schema":{"type":"integer","title":"Before"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/memory/explain":{"get":{"summary":"Explain","description":"Retrieval playground: given a query, show EXACTLY what would be injected\nand why. This is the transparency surface -- a customer can see which facts\nthe model was given, which were excluded as superseded, how the cacheable\nprefix is assembled, and what each stage cost.","operationId":"explain_v1_memory_explain_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","title":"Q"}},{"name":"subject","in":"query","required":false,"schema":{"type":"string","title":"Subject"}},{"name":"agent_type","in":"query","required":false,"schema":{"type":"string","default":"telegram","title":"Agent Type"}},{"name":"k","in":"query","required":false,"schema":{"type":"integer","default":6,"title":"K"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/status":{"get":{"summary":"Status","description":"Operational view for one tenant: sources connected, queue health.","operationId":"status_v1_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subjects":{"get":{"summary":"Subjects","description":"Who this tenant holds data about. Article 30 needs this to be answerable.","operationId":"subjects_v1_subjects_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subject/{external_id}/export":{"get":{"summary":"Export Subject","description":"Article 15/20: everything held about one person, in a portable form --\nthe derived facts, their full supersession history, and the verbatim\ntranscript decrypted with that subject's own key.","operationId":"export_subject_v1_subject__external_id__export_get","parameters":[{"name":"external_id","in":"path","required":true,"schema":{"type":"string","title":"External Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/tenant/export":{"get":{"summary":"Export Tenant","description":"Everything, for the customer that owns it.\n\nPer-subject export answers a data subject request. This answers \"we are\nleaving\" -- and being easy to leave is what makes people comfortable\narriving. Offboarding was previously a request to a human, which is the\nsame as not having it.\n\nStreamed as NDJSON, one record per line, because a real tenant is 10k facts\nand thousands of turns: assembling that as a single JSON object in memory\nis how an export endpoint takes the process down on the day someone\nactually uses it. Each line is independently parseable, so a consumer can\nprocess it without holding the whole export either.\n\nIncludes what the per-subject export cannot: org-scope facts, which belong\nto the company rather than to any one person, and the audit trail.","operationId":"export_tenant_v1_tenant_export_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subject/{external_id}":{"delete":{"summary":"Erase Subject Ep","description":"Article 17. Destroys the subject's encryption key: derived facts are\ndeleted outright and the append-only transcript becomes permanently\nunreadable without rewriting it. The audit row survives to evidence that\nthe erasure happened.","operationId":"erase_subject_ep_v1_subject__external_id__delete","parameters":[{"name":"external_id","in":"path","required":true,"schema":{"type":"string","title":"External Id"}},{"name":"confirm","in":"query","required":false,"schema":{"type":"string","title":"Confirm"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/healthz":{"get":{"summary":"Healthz","description":"Public callers get liveness and nothing else — whether we are in mock\nmode, and which model we run, is not the internet's business. Detail is\nreturned only to callers on the local network.","operationId":"healthz_healthz_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[]}}},"components":{"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"A vrv_live_ key. Scope it with memctl --scope."}}},"security":[{"apiKey":[]}]}