We are in official beta.

Personal Vault

A private document store per customer — file receipts and records, then ask plain-English questions about what is due, what was spent, and what a document said

13 endpoints in this category. All require X-API-Key header.


Vault: Ask

POST /api/VaultAsk 1 token

Answers a plain-English question about one customer's stored documents — when something is due, how much was spent, what a document said. Common questions are answered from precomputed dates with no AI call at all, which is why they return in milliseconds.

Due dates are computed when a document is filed, never at question time — so the answer is a stored row you can cite, not a model's arithmetic. "usedModel" tells you whether inference was spent. Returns 503 until the vault settings are configured.
Parameters
NameTypeRequiredDescription
question string required The question, in plain English (e.g. "When is my cat due for vaccinations?")
tenantId string optional Admin key only — the vault to read. A client key always reads its own vault and cannot name another
Request Example
JSON
{"question": "When is my cat due for vaccinations?"}
Response Example
JSON
{"success": true, "intent": "due", "answer": "Fluffy: rabies booster is due in about 19 months — 14 March 2028.", "usedModel": false, "latencyMs": 3, "resolution": "alias", "unconfirmed": false, "citation": {"documentId": 4471, "derivedFrom": "14 March 2025"}}
Code Examples
curl -X POST "https://api.docbutterfly.com/api/VaultAsk" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"question": "When is my cat due for vaccinations?"}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{""question"": ""When is my cat due for vaccinations?""}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/VaultAsk", content);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
import requests
import json

url = "https://api.docbutterfly.com/api/VaultAsk"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{"question": "When is my cat due for vaccinations?"}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

data = response.json()
print(json.dumps(data, indent=2))
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  POST                              │
│  URI:     https://api.docbutterfly.com/api/VaultAsk
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {
│      "question": "When is my cat due for vaccinations?"
│    }
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "POST"
3. Set URI to "https://api.docbutterfly.com/api/VaultAsk"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed
Try in Testbed

Vault: File Document

POST /api/VaultIngestDocument 5 tokens

Files a receipt, statement or record into the customer's own document store: the original goes to their private container addressed by content hash, and any dated facts become searchable records with their follow-up dates already worked out.

Idempotent by content hash: filing the same photo twice returns duplicate:true and spends no second extraction. When confidence is below the threshold, needsConfirmation is true and the fact should be shown for one-tap confirmation rather than asserted.
Parameters
NameTypeRequiredDescription
fileContent string required The document as base64
mediaType string optional MIME type of the document (default: application/octet-stream)
fileName string optional Original filename, kept as metadata (never part of the address)
fields object optional Already-parsed facts: entityName, entityKind, eventKind, occurredOn, amount, currency, confidence, attrs
text string optional Document text to index for search
tenantId string optional Admin key only — the vault to file into
Request Example
JSON
{"fileContent": "<base64>", "mediaType": "application/pdf", "fields": {"entityName": "Fluffy", "entityKind": "pet", "eventKind": "vaccination", "occurredOn": "2025-03-14", "confidence": 0.94, "attrs": {"vaccine": "Rabies 3-year"}}}
Response Example
JSON
{"success": true, "duplicate": false, "documentId": 4471, "obligations": [{"kind": "rabies_booster", "due_on": "2028-03-14", "rule_id": "pet.rabies_booster", "rule_version": 2}], "needsConfirmation": false}
Code Examples
curl -X POST "https://api.docbutterfly.com/api/VaultIngestDocument" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"fileContent": "<base64>", "mediaType": "application/pdf", "fields": {"entityName": "Fluffy", "entityKind": "pet", "eventKind": "vaccination", "occurredOn": "2025-03-14", "confidence": 0.94, "attrs": {"vaccine": "Rabies 3-year"}}}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{""fileContent"": ""<base64>"", ""mediaType"": ""application/pdf"", ""fields"": {""entityName"": ""Fluffy"", ""entityKind"": ""pet"", ""eventKind"": ""vaccination"", ""occurredOn"": ""2025-03-14"", ""confidence"": 0.94, ""attrs"": {""vaccine"": ""Rabies 3-year""}}}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/VaultIngestDocument", content);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
import requests
import json

url = "https://api.docbutterfly.com/api/VaultIngestDocument"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{"fileContent": "<base64>", "mediaType": "application/pdf", "fields": {"entityName": "Fluffy", "entityKind": "pet", "eventKind": "vaccination", "occurredOn": "2025-03-14", "confidence": 0.94, "attrs": {"vaccine": "Rabies 3-year"}}}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

data = response.json()
print(json.dumps(data, indent=2))
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  POST                              │
│  URI:     https://api.docbutterfly.com/api/VaultIngestDocument
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {
│      "fileContent": "\u003Cbase64\u003E",
│      "mediaType": "application/pdf",
│      "fields": {
│        "entityName": "Fluffy",
│        "entityKind": "pet",
│        "eventKind": "vaccination",
│        "occurredOn": "2025-03-14",
│        "confidence": 0.94,
│        "attrs": {
│          "vaccine": "Rabies 3-year"
│        }
│      }
│    }
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "POST"
3. Set URI to "https://api.docbutterfly.com/api/VaultIngestDocument"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed
Try in Testbed

Vault: What Is Due

POST /api/VaultUpcoming 1 token

Lists what the customer owes attention to, soonest first — renewals, boosters, inspections, service intervals — each with the record it was worked out from.

Reads an indexed date column, so it stays fast regardless of how many documents the customer has filed.
Parameters
NameTypeRequiredDescription
withinDays number optional How far ahead to look (default: 90)
tenantId string optional Admin key only — the vault to read
Request Example
JSON
{"withinDays": 30}
Response Example
JSON
{"success": true, "count": 1, "obligations": [{"entity_name": "Camry", "kind": "registration_renewal", "due_on": "2026-09-01", "status": "open"}]}
Code Examples
curl -X POST "https://api.docbutterfly.com/api/VaultUpcoming" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"withinDays": 30}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{""withinDays"": 30}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/VaultUpcoming", content);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
import requests
import json

url = "https://api.docbutterfly.com/api/VaultUpcoming"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{"withinDays": 30}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

data = response.json()
print(json.dumps(data, indent=2))
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  POST                              │
│  URI:     https://api.docbutterfly.com/api/VaultUpcoming
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {
│      "withinDays": 30
│    }
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "POST"
3. Set URI to "https://api.docbutterfly.com/api/VaultUpcoming"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed
Try in Testbed

Vault: List Things

POST /api/VaultEntities 1 token

Lists the things this customer's vault knows about — their pets, vehicles, properties, policies — with the alternative names each one answers to.

Aliases are what let a question say "my cat" or "the orange one" and still reach the right record.
Parameters
NameTypeRequiredDescription
kind string optional Filter to one kind: pet, vehicle, property, policy, person, merchant
tenantId string optional Admin key only — the vault to read
Request Example
JSON
{"kind": "pet"}
Response Example
JSON
{"success": true, "count": 1, "entities": [{"id": 12, "kind": "pet", "display_name": "Fluffy", "aliases": ["the orange one", "kitty"]}]}
Code Examples
curl -X POST "https://api.docbutterfly.com/api/VaultEntities" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"kind": "pet"}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{""kind"": ""pet""}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/VaultEntities", content);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
import requests
import json

url = "https://api.docbutterfly.com/api/VaultEntities"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{"kind": "pet"}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

data = response.json()
print(json.dumps(data, indent=2))
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  POST                              │
│  URI:     https://api.docbutterfly.com/api/VaultEntities
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {
│      "kind": "pet"
│    }
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "POST"
3. Set URI to "https://api.docbutterfly.com/api/VaultEntities"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed
Try in Testbed

Vault: Confirm Record

POST /api/VaultConfirmEvent 1 token

Confirms a record the extractor was not certain about. One call marks the fact as verified by a person and clears the "unconfirmed" flag from every date worked out from it.

Idempotent — confirming twice is harmless. Returns 404 when the record is not in this customer's vault.
Parameters
NameTypeRequiredDescription
eventId number required The record to confirm
tenantId string optional Admin key only — the vault to act on
Request Example
JSON
{"eventId": 881}
Response Example
JSON
{"success": true, "event": {"id": 881, "confirmed_at": "2026-08-25T14:02:11Z", "confidence": 1}}
Code Examples
curl -X POST "https://api.docbutterfly.com/api/VaultConfirmEvent" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"eventId": 881}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{""eventId"": 881}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/VaultConfirmEvent", content);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
import requests
import json

url = "https://api.docbutterfly.com/api/VaultConfirmEvent"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{"eventId": 881}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

data = response.json()
print(json.dumps(data, indent=2))
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  POST                              │
│  URI:     https://api.docbutterfly.com/api/VaultConfirmEvent
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {
│      "eventId": 881
│    }
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "POST"
3. Set URI to "https://api.docbutterfly.com/api/VaultConfirmEvent"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed
Try in Testbed

Vault: File My Own Record

POST /api/vault/ingest 5 tokens

Reads a resume, letter or personal record and files what it says about the customer themselves — names, contact details, addresses, employers, schools and references — into their own profile, each fact carrying the document and page it came from. Answers with counts only, never with the values it read, so a whole folder can be filed and logged safely.

Idempotent by content hash. Facts are deduplicated on a normalized key, so one employer named across nine resumes stays one record; where two documents disagree the newer one wins field by field, and every document that ever asserted a fact is kept. No national identity number is ever stored. Returns 503 until the vault settings are configured.
Parameters
NameTypeRequiredDescription
fileContent string required The document as base64. PDF, DOCX, Markdown or plain text
fileName string optional Original filename. Decides how the document is read when the media type is generic
mediaType string optional MIME type of the document (default: application/octet-stream)
observedAt string optional How OLD the document is (ISO timestamp). A newer document wins where two disagree, so this is the document's own date, not the time it was filed (default: now)
sensitivity string optional normal or restricted. A restricted document is never indexed for search (default: normal)
tenantId string optional Admin key only — the vault to file into
Request Example
JSON
{"fileContent": "<base64>", "fileName": "resume.docx", "observedAt": "2026-07-27T00:00:00Z"}
Response Example
JSON
{"success": true, "duplicate": false, "documentId": 4482, "kind": "docx", "factsExtracted": 31, "inserted": 24, "updated": 5, "unchanged": 2, "bySection": {"person": 4, "contacts": 2, "addresses": 1, "employment": 16, "education": 5, "references": 3}, "confidence": {"min": 0.55, "mean": 0.86, "max": 0.98}}
Code Examples
curl -X POST "https://api.docbutterfly.com/api/vault/ingest" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"fileContent": "<base64>", "fileName": "resume.docx", "observedAt": "2026-07-27T00:00:00Z"}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{""fileContent"": ""<base64>"", ""fileName"": ""resume.docx"", ""observedAt"": ""2026-07-27T00:00:00Z""}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/vault/ingest", content);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
import requests
import json

url = "https://api.docbutterfly.com/api/vault/ingest"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{"fileContent": "<base64>", "fileName": "resume.docx", "observedAt": "2026-07-27T00:00:00Z"}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

data = response.json()
print(json.dumps(data, indent=2))
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  POST                              │
│  URI:     https://api.docbutterfly.com/api/vault/ingest
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {
│      "fileContent": "\u003Cbase64\u003E",
│      "fileName": "resume.docx",
│      "observedAt": "2026-07-27T00:00:00Z"
│    }
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "POST"
3. Set URI to "https://api.docbutterfly.com/api/vault/ingest"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed
Try in Testbed

Vault: My Own Details

POST /api/vault/self-profile 1 token

Returns everything the vault holds about the customer themselves — name, contact details, address history, employment, education and references, plus an open-ended list of every other fact their documents stated about them — assembled into one record, with the source document, page and confidence behind every fact.

History sections come back most recent first, which is the order the long identity forms ask for. A field the documents never stated is null rather than blank — unknown and empty are different answers on a form. employmentResolved sits beside employment: the raw rows are the evidence, the resolved rows are one entry per employer per stint, and at most one address is ever marked current. "other" is the open-ended list — an identifier, a vehicle, an allergy, a membership: anything a document said that the sections above have no box for. A fact whose label looks like an identifier comes back MASKED, with the mask in place of the value rather than beside it; pass that fact's factKey as "reveal" to get the full value, and the request is written to the customer's own reveal history. ssnStored says whether the vault holds a Social Security number — it used to be a hardcoded false and is now the truth.
Parameters
NameTypeRequiredDescription
tenantId string optional Admin key only — the vault to read. A client key always reads its own
reveal string optional The factKey of one masked identifier to return in full. The reveal is recorded and shows in the customer's own history
Request Example
JSON
{}
Response Example
JSON
{"success": true, "shape": {"person": {"kind": "object", "fields": ["firstName", "middleName", "lastName", "suffix", "otherNames", "dateOfBirth", "placeOfBirth", "citizenship", "ssnStored"], "otherNames": ["name", "from", "to"], "placeOfBirth": ["city", "state", "country"]}, "contacts": {"kind": "object", "fields": ["emails", "phones"], "emails": ["value", "primary"], "phones": ["value", "kind", "primary"]}, "addresses": {"kind": "array", "fields": ["line1", "line2", "city", "state", "postalCode", "country", "from", "to", "current"]}, "employment": {"kind": "array", "fields": ["employer", "title", "address", "supervisor", "from", "to", "current", "description"], "supervisor": ["name", "phone", "email"]}, "education": {"kind": "array", "fields": ["school", "degree", "field", "address", "from", "to", "graduated"]}, "references": {"kind": "array", "fields": ["name", "relationship", "phone", "email", "address"]}, "other": {"kind": "array", "fields": ["label", "rawLabel", "key", "value", "valueType", "sensitive", "masked", "revealed", "why"]}, "otherByKey": {"kind": "object", "fields": []}, "employmentResolved": {"kind": "array", "fields": ["employer", "title", "address", "supervisor", "from", "to", "current", "description", "titles", "rowCount", "settled", "factKeys", "sources", "needsReview", "conflicts"], "supervisor": ["name", "phone", "email"], "conflicts": ["field", "values"]}, "sources": {"kind": "array", "fields": ["documentId", "fileName", "ingestedAt"]}, "provenance": ["documentId", "page", "confidence", "observedAt", "source", "factKey"], "address": ["line1", "line2", "city", "state", "postalCode", "country"], "dateFormat": "yyyy-mm | yyyy-mm-dd"}, "profile": {"person": {"firstName": "Alex", "lastName": "Rivera", "ssnStored": true}, "contacts": {"emails": [{"value": "alex@example.com", "primary": true, "provenance": {"documentId": 4482, "page": 1, "confidence": 0.97}}], "phones": []}, "addresses": [], "employment": [], "education": [], "references": [], "other": [{"label": "Blood type", "key": "bloodtype", "value": "O+", "valueType": "text", "sensitive": false, "masked": false, "provenance": {"documentId": 4483, "page": 2, "confidence": 0.94, "factKey": "other:bloodtype|o"}}, {"label": "Driver license number", "key": "driverlicensenumber", "value": "••••-••••-8901", "valueType": "text", "sensitive": true, "masked": true, "provenance": {"documentId": 4483, "page": 1, "confidence": 0.99, "factKey": "other:driverlicensenumber|s123 4567 8901"}}], "sources": [{"documentId": 4482, "fileName": "resume.docx", "ingestedAt": "2026-09-02T21:40:00Z"}]}, "counts": {"sections": [{"section": "contacts", "n": 2, "min_conf": 0.9, "max_conf": 0.97, "avg_conf": 0.94}, {"section": "employment", "n": 16, "min_conf": 0.72, "max_conf": 0.98, "avg_conf": 0.9}, {"section": "person", "n": 4, "min_conf": 0.88, "max_conf": 0.99, "avg_conf": 0.94}], "documents": 3}}
Code Examples
curl -X POST "https://api.docbutterfly.com/api/vault/self-profile" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/vault/self-profile", content);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
import requests
import json

url = "https://api.docbutterfly.com/api/vault/self-profile"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

data = response.json()
print(json.dumps(data, indent=2))
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  POST                              │
│  URI:     https://api.docbutterfly.com/api/vault/self-profile
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {}
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "POST"
3. Set URI to "https://api.docbutterfly.com/api/vault/self-profile"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed
Try in Testbed

Vault: Correct My Own Details

PUT /api/vault/self-profile 1 token

Stores a fact the customer entered themselves — a supervisor's phone number, a date of birth, a reference — into their own profile. A manually entered fact outranks anything read out of a document, permanently, so a later upload cannot revert a correction.

A PUT, not a POST: it replaces a fact rather than appending one. The value replaces field for field — an empty box means "there is no answer", which is different from a document simply not mentioning it. Dates are normalized the same way an extracted date is, so a typed answer and a read one land as the same record. No national identity number is stored whichever way it arrives.
Parameters
NameTypeRequiredDescription
section string required person, contacts, addresses, employment, education or references
value object required The edited entry, in the shape that section uses
factKey string optional The fact being replaced or removed, from the provenance on the fact
remove boolean optional Delete the fact named by factKey instead of writing one (default: false)
edits array optional Several of the above applied together
tenantId string optional Admin key only — the vault to write. A client key always writes its own
Request Example
JSON
{"section": "employment", "factKey": "employment:acme|analyst|2019-06", "value": {"employer": "Acme", "title": "Analyst", "from": "2019-06", "supervisor": {"name": "Dana Reed", "phone": "555-0100"}}}
Response Example
JSON
{"success": true, "written": 1, "removed": 0, "sections": {"employment": 1}, "shape": {"person": {"kind": "object", "fields": ["firstName", "middleName", "lastName", "suffix", "otherNames", "dateOfBirth", "placeOfBirth", "citizenship", "ssnStored"], "otherNames": ["name", "from", "to"], "placeOfBirth": ["city", "state", "country"]}, "contacts": {"kind": "object", "fields": ["emails", "phones"], "emails": ["value", "primary"], "phones": ["value", "kind", "primary"]}, "addresses": {"kind": "array", "fields": ["line1", "line2", "city", "state", "postalCode", "country", "from", "to", "current"]}, "employment": {"kind": "array", "fields": ["employer", "title", "address", "supervisor", "from", "to", "current", "description"], "supervisor": ["name", "phone", "email"]}, "education": {"kind": "array", "fields": ["school", "degree", "field", "address", "from", "to", "graduated"]}, "references": {"kind": "array", "fields": ["name", "relationship", "phone", "email", "address"]}, "other": {"kind": "array", "fields": ["label", "rawLabel", "key", "value", "valueType", "sensitive", "masked", "revealed", "why"]}, "otherByKey": {"kind": "object", "fields": []}, "employmentResolved": {"kind": "array", "fields": ["employer", "title", "address", "supervisor", "from", "to", "current", "description", "titles", "rowCount", "settled", "factKeys", "sources", "needsReview", "conflicts"], "supervisor": ["name", "phone", "email"], "conflicts": ["field", "values"]}, "sources": {"kind": "array", "fields": ["documentId", "fileName", "ingestedAt"]}, "provenance": ["documentId", "page", "confidence", "observedAt", "source", "factKey"], "address": ["line1", "line2", "city", "state", "postalCode", "country"], "dateFormat": "yyyy-mm | yyyy-mm-dd"}, "profile": {"employment": [], "employmentResolved": [], "addresses": []}}
Code Examples
curl -X PUT "https://api.docbutterfly.com/api/vault/self-profile" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"section": "employment", "factKey": "employment:acme|analyst|2019-06", "value": {"employer": "Acme", "title": "Analyst", "from": "2019-06", "supervisor": {"name": "Dana Reed", "phone": "555-0100"}}}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{""section"": ""employment"", ""factKey"": ""employment:acme|analyst|2019-06"", ""value"": {""employer"": ""Acme"", ""title"": ""Analyst"", ""from"": ""2019-06"", ""supervisor"": {""name"": ""Dana Reed"", ""phone"": ""555-0100""}}}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/vault/self-profile", content);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
import requests
import json

url = "https://api.docbutterfly.com/api/vault/self-profile"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{"section": "employment", "factKey": "employment:acme|analyst|2019-06", "value": {"employer": "Acme", "title": "Analyst", "from": "2019-06", "supervisor": {"name": "Dana Reed", "phone": "555-0100"}}}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

data = response.json()
print(json.dumps(data, indent=2))
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  PUT                               │
│  URI:     https://api.docbutterfly.com/api/vault/self-profile
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {
│      "section": "employment",
│      "factKey": "employment:acme|analyst|2019-06",
│      "value": {
│        "employer": "Acme",
│        "title": "Analyst",
│        "from": "2019-06",
│        "supervisor": {
│          "name": "Dana Reed",
│          "phone": "555-0100"
│        }
│      }
│    }
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "PUT"
3. Set URI to "https://api.docbutterfly.com/api/vault/self-profile"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed
Try in Testbed

Vault: Re-read a Filed Document

POST /api/vault/documents/{id}/re-extract 5 tokens

Re-runs extraction over a document the vault already holds, reading the stored original — the customer does not upload it again. Use it when the way documents are read improves: the whole vault picks up the change without a byte of the original leaving the customer's storage.

Address the document by its numeric id or by the sha256 of its bytes, so a caller holding the original file can name it without knowing any id. Idempotent: facts merge onto the same records, so running it twice reports everything unchanged rather than duplicating a history. Answers with counts only, never with the values it read. 404 when the document is not in this customer's vault, 410 when the stored original is gone, 503 until the vault settings are configured.
Parameters
NameTypeRequiredDescription
observedAt string optional Override how OLD the document is (ISO timestamp). By default the age recorded when it was first filed is reused, so a re-read never outranks a newer document (default: the document's recorded age)
tenantId string optional Admin key only — the vault to act on
Request Example
JSON
{}
Response Example
JSON
{"success": true, "reExtracted": true, "documentId": 4482, "sha256": "e3b0c44298fc1c149afbf4c8996fb924…", "fileName": "resume.docx", "kind": "docx", "pageCount": 3, "observedAt": "2026-07-27T00:00:00Z", "factsExtracted": 31, "inserted": 0, "updated": 3, "unchanged": 28, "bySection": {"person": 4, "employment": 16}, "confidence": {"min": 0.72, "max": 0.99, "sum": 27.9, "n": 31}, "priorAnswers": {"recognized": false, "reason": "not a known completed form"}, "truncated": false, "charsDropped": 0, "windows": 1, "alternates": 0, "outputTruncated": false, "usedModel": "gpt-4o-successor", "latencyMs": 4120}
Code Examples
curl -X POST "https://api.docbutterfly.com/api/vault/documents/{id}/re-extract" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/vault/documents/{id}/re-extract", content);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
import requests
import json

url = "https://api.docbutterfly.com/api/vault/documents/{id}/re-extract"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

data = response.json()
print(json.dumps(data, indent=2))
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  POST                              │
│  URI:     https://api.docbutterfly.com/api/vault/documents/{id}/re-extract
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {}
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "POST"
3. Set URI to "https://api.docbutterfly.com/api/vault/documents/{id}/re-extract"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed
Try in Testbed

Vault: My Documents

GET /api/vault/documents 1 token

Lists the documents in the customer's vault, each with how many versions of it have been filed and how much text was read from the newest one.

A re-photographed or re-scanned document is recognized as a new VERSION of the one already filed, not as a second document, so this list stays the length a person expects. paginated is false where the format has no pages at all — a Word file or a text note — and the page numbers beside it are then section indices rather than pages.
Parameters
NameTypeRequiredDescription
limit integer optional How many documents to return (default: 200)
tenantId string optional Admin key only — the vault to read. A client key always reads its own
Request Example
JSON
{}
Response Example
JSON
{"success": true, "count": 1, "documents": [{"documentId": 4482, "fileName": "lease-2025.pdf", "mediaType": "application/pdf", "versions": 2, "latestVersion": 2, "pageCount": 2, "paginated": true, "pages": 2}]}
Code Examples
curl -X GET "https://api.docbutterfly.com/api/vault/documents" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/vault/documents", content);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
import requests
import json

url = "https://api.docbutterfly.com/api/vault/documents"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

data = response.json()
print(json.dumps(data, indent=2))
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  GET                               │
│  URI:     https://api.docbutterfly.com/api/vault/documents
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {}
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "GET"
3. Set URI to "https://api.docbutterfly.com/api/vault/documents"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed
Try in Testbed

Vault: Document History

GET /api/vault/documents/{documentId}/versions 1 token

Returns the version chain for one document, newest first, with how each version was recognized as belonging to it.

matchedBy says why a version belongs to this document: new is a first version, sha256 is the identical file again, and text is a re-scan matched on the normalized text of its opening pages, with the similarity that justified it in matchScore. Facts read from an earlier version keep their records and are marked superseded rather than deleted. A document that is not this vault's answers 404, not 403.
Parameters
NameTypeRequiredDescription
documentId integer required In the path: /api/vault/documents/{documentId}/versions
tenantId string optional Admin key only — the vault to read. A client key always reads its own
Request Example
JSON
{}
Response Example
JSON
{"success": true, "documentId": 4482, "count": 2, "latestVersion": 2, "fileName": "lease-2025-rescan.pdf", "versions": [{"version": 2, "matchedBy": "text", "matchScore": 0.97, "supersedesVersion": 1, "pageCount": 2, "paginated": true, "pages": 2, "ocrEngine": "pdf-parse", "fileName": "lease-2025-rescan.pdf"}, {"version": 1, "matchedBy": "new", "matchScore": null, "supersedesVersion": null, "pages": 2}]}
Code Examples
curl -X GET "https://api.docbutterfly.com/api/vault/documents/{documentId}/versions" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/vault/documents/{documentId}/versions", content);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
import requests
import json

url = "https://api.docbutterfly.com/api/vault/documents/{documentId}/versions"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

data = response.json()
print(json.dumps(data, indent=2))
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  GET                               │
│  URI:     https://api.docbutterfly.com/api/vault/documents/{documentId}/versions
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {}
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "GET"
3. Set URI to "https://api.docbutterfly.com/api/vault/documents/{documentId}/versions"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed
Try in Testbed

Vault: Document Text

GET /api/vault/documents/{documentId}/versions/{versionNo}/pages 1 token

Returns the text of one version of one document, page by page — what the vault actually read, and what an answer citing that page is quoting.

Page numbers are honest or absent. Where the format has pages the number is the page; where it has none — Word, Markdown, plain text — paginated is false and the number is a section index, which is why an answer drawn from such a version cites the document and the version and names no page.
Parameters
NameTypeRequiredDescription
documentId integer required In the path: /api/vault/documents/{documentId}/versions/{versionNo}/pages
versionNo integer required In the path — the version to read
tenantId string optional Admin key only — the vault to read. A client key always reads its own
Request Example
JSON
{}
Response Example
JSON
{"success": true, "documentId": 4482, "version": 2, "fileName": "lease-2025.pdf", "pageCount": 2, "paginated": true, "ocrEngine": "pdf-parse", "pages": [{"page": 1, "text": "RESIDENTIAL LEASE AGREEMENT ..."}, {"page": 2, "text": "SECTION 9. PETS. ..."}]}
Code Examples
curl -X GET "https://api.docbutterfly.com/api/vault/documents/{documentId}/versions/{versionNo}/pages" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/vault/documents/{documentId}/versions/{versionNo}/pages", content);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
import requests
import json

url = "https://api.docbutterfly.com/api/vault/documents/{documentId}/versions/{versionNo}/pages"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

data = response.json()
print(json.dumps(data, indent=2))
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  GET                               │
│  URI:     https://api.docbutterfly.com/api/vault/documents/{documentId}/versions/{versionNo}/pages
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {}
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "GET"
3. Set URI to "https://api.docbutterfly.com/api/vault/documents/{documentId}/versions/{versionNo}/pages"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed
Try in Testbed

Vault: Search

GET /api/vault/search 1 token

Searches everything one customer's vault holds at once — document names, the text on their pages, the facts read out of them, the answers kept from forms they have filled in, and their contacts — and returns the hits ranked, each one saying which document and page it came from.

Identifiers stay masked. A fact the vault masks — a Social Security number, a policy number, an account number — is matched and returned as its mask, so a search can never be used to confirm a value it will not display; the last four digits the mask already shows are matchable, and nothing else is. Revealing one full value is a separate, audited request on Vault: My Own Details. An empty q is not an error: it answers with the most recently filed documents, which is what a search box should show before anyone types.
Parameters
NameTypeRequiredDescription
q string optional What to look for. An empty search returns the most recently filed documents
limit integer optional How many hits to return, 1-100 (default: 20)
offset integer optional How far into the ranked list to start (default: 0)
kinds string optional Comma-separated list to narrow the search: document, fact, answer, contact. Omitted searches all of them
tenantId string optional Admin key only — the vault to search. A client key always searches its own
Request Example
JSON
{}
Response Example
JSON
{"success": true, "query": "lease", "total": 3, "offset": 0, "limit": 20, "hasMore": false, "counts": {"document": 2, "fact": 1, "contact": 0, "answer": 0}, "results": [{"kind": "document", "matchedOn": "name", "title": "lease-2025.pdf", "documentId": 4482, "version": 2, "page": null, "score": 1}, {"kind": "document", "matchedOn": "page", "title": "lease-2025.pdf", "documentId": 4482, "version": 2, "page": 2, "snippet": "…SECTION 9. PETS. Pets are permitted with the prior written consent…", "score": 0.42}]}
Code Examples
curl -X GET "https://api.docbutterfly.com/api/vault/search" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/vault/search", content);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
import requests
import json

url = "https://api.docbutterfly.com/api/vault/search"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

data = response.json()
print(json.dumps(data, indent=2))
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  GET                               │
│  URI:     https://api.docbutterfly.com/api/vault/search
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {}
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "GET"
3. Set URI to "https://api.docbutterfly.com/api/vault/search"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed
Try in Testbed