curl --request POST \
--url https://api.example.com/v0/records \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"idempotency_key": "<string>",
"source": {
"corpus_id": "<string>",
"namespace": "<string>",
"record_key": "<string>"
},
"content": {
"kind": "text",
"text": "<string>"
},
"source_revision": "<string>",
"source_position": "<string>",
"extensions": {},
"provenance": {
"source_blob_ids": [
"<string>"
],
"producer": "<string>",
"producer_version": "<string>"
}
}
'import requests
url = "https://api.example.com/v0/records"
payload = {
"idempotency_key": "<string>",
"source": {
"corpus_id": "<string>",
"namespace": "<string>",
"record_key": "<string>"
},
"content": {
"kind": "text",
"text": "<string>"
},
"source_revision": "<string>",
"source_position": "<string>",
"extensions": {},
"provenance": {
"source_blob_ids": ["<string>"],
"producer": "<string>",
"producer_version": "<string>"
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
idempotency_key: '<string>',
source: {corpus_id: '<string>', namespace: '<string>', record_key: '<string>'},
content: {kind: 'text', text: '<string>'},
source_revision: '<string>',
source_position: '<string>',
extensions: {},
provenance: {
source_blob_ids: ['<string>'],
producer: '<string>',
producer_version: '<string>'
}
})
};
fetch('https://api.example.com/v0/records', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/v0/records",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'idempotency_key' => '<string>',
'source' => [
'corpus_id' => '<string>',
'namespace' => '<string>',
'record_key' => '<string>'
],
'content' => [
'kind' => 'text',
'text' => '<string>'
],
'source_revision' => '<string>',
'source_position' => '<string>',
'extensions' => [
],
'provenance' => [
'source_blob_ids' => [
'<string>'
],
'producer' => '<string>',
'producer_version' => '<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/v0/records"
payload := strings.NewReader("{\n \"idempotency_key\": \"<string>\",\n \"source\": {\n \"corpus_id\": \"<string>\",\n \"namespace\": \"<string>\",\n \"record_key\": \"<string>\"\n },\n \"content\": {\n \"kind\": \"text\",\n \"text\": \"<string>\"\n },\n \"source_revision\": \"<string>\",\n \"source_position\": \"<string>\",\n \"extensions\": {},\n \"provenance\": {\n \"source_blob_ids\": [\n \"<string>\"\n ],\n \"producer\": \"<string>\",\n \"producer_version\": \"<string>\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/v0/records")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"idempotency_key\": \"<string>\",\n \"source\": {\n \"corpus_id\": \"<string>\",\n \"namespace\": \"<string>\",\n \"record_key\": \"<string>\"\n },\n \"content\": {\n \"kind\": \"text\",\n \"text\": \"<string>\"\n },\n \"source_revision\": \"<string>\",\n \"source_position\": \"<string>\",\n \"extensions\": {},\n \"provenance\": {\n \"source_blob_ids\": [\n \"<string>\"\n ],\n \"producer\": \"<string>\",\n \"producer_version\": \"<string>\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v0/records")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"idempotency_key\": \"<string>\",\n \"source\": {\n \"corpus_id\": \"<string>\",\n \"namespace\": \"<string>\",\n \"record_key\": \"<string>\"\n },\n \"content\": {\n \"kind\": \"text\",\n \"text\": \"<string>\"\n },\n \"source_revision\": \"<string>\",\n \"source_position\": \"<string>\",\n \"extensions\": {},\n \"provenance\": {\n \"source_blob_ids\": [\n \"<string>\"\n ],\n \"producer\": \"<string>\",\n \"producer_version\": \"<string>\"\n }\n}"
response = http.request(request)
puts response.read_body{
"receipt_id": "<string>",
"state": "pending",
"diagnostics": [
{
"code": "<string>",
"message": "<string>",
"retryable": true,
"field": "<string>",
"resync_url": "<string>"
}
],
"source": {
"corpus_id": "<string>",
"namespace": "<string>",
"record_key": "<string>"
},
"processing": {
"state": "queued",
"phase": "materialization",
"message": "<string>"
},
"outcome": "created",
"record_id": "<string>",
"version_id": "<string>",
"availability": {
"state": "materialized",
"is_current": true,
"searchable": true
}
}{
"code": "<string>",
"message": "<string>",
"retryable": true,
"field": "<string>",
"resync_url": "<string>"
}Ingest record
Commit durable input, Receipt and dispatch intent before responding. Same key and canonical request returns same Receipt; changed request conflicts. A new source revision corrects the Record. All accepted/replayed submissions use 202, even when a replayed Receipt has resolved.
curl --request POST \
--url https://api.example.com/v0/records \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"idempotency_key": "<string>",
"source": {
"corpus_id": "<string>",
"namespace": "<string>",
"record_key": "<string>"
},
"content": {
"kind": "text",
"text": "<string>"
},
"source_revision": "<string>",
"source_position": "<string>",
"extensions": {},
"provenance": {
"source_blob_ids": [
"<string>"
],
"producer": "<string>",
"producer_version": "<string>"
}
}
'import requests
url = "https://api.example.com/v0/records"
payload = {
"idempotency_key": "<string>",
"source": {
"corpus_id": "<string>",
"namespace": "<string>",
"record_key": "<string>"
},
"content": {
"kind": "text",
"text": "<string>"
},
"source_revision": "<string>",
"source_position": "<string>",
"extensions": {},
"provenance": {
"source_blob_ids": ["<string>"],
"producer": "<string>",
"producer_version": "<string>"
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
idempotency_key: '<string>',
source: {corpus_id: '<string>', namespace: '<string>', record_key: '<string>'},
content: {kind: 'text', text: '<string>'},
source_revision: '<string>',
source_position: '<string>',
extensions: {},
provenance: {
source_blob_ids: ['<string>'],
producer: '<string>',
producer_version: '<string>'
}
})
};
fetch('https://api.example.com/v0/records', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/v0/records",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'idempotency_key' => '<string>',
'source' => [
'corpus_id' => '<string>',
'namespace' => '<string>',
'record_key' => '<string>'
],
'content' => [
'kind' => 'text',
'text' => '<string>'
],
'source_revision' => '<string>',
'source_position' => '<string>',
'extensions' => [
],
'provenance' => [
'source_blob_ids' => [
'<string>'
],
'producer' => '<string>',
'producer_version' => '<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/v0/records"
payload := strings.NewReader("{\n \"idempotency_key\": \"<string>\",\n \"source\": {\n \"corpus_id\": \"<string>\",\n \"namespace\": \"<string>\",\n \"record_key\": \"<string>\"\n },\n \"content\": {\n \"kind\": \"text\",\n \"text\": \"<string>\"\n },\n \"source_revision\": \"<string>\",\n \"source_position\": \"<string>\",\n \"extensions\": {},\n \"provenance\": {\n \"source_blob_ids\": [\n \"<string>\"\n ],\n \"producer\": \"<string>\",\n \"producer_version\": \"<string>\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/v0/records")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"idempotency_key\": \"<string>\",\n \"source\": {\n \"corpus_id\": \"<string>\",\n \"namespace\": \"<string>\",\n \"record_key\": \"<string>\"\n },\n \"content\": {\n \"kind\": \"text\",\n \"text\": \"<string>\"\n },\n \"source_revision\": \"<string>\",\n \"source_position\": \"<string>\",\n \"extensions\": {},\n \"provenance\": {\n \"source_blob_ids\": [\n \"<string>\"\n ],\n \"producer\": \"<string>\",\n \"producer_version\": \"<string>\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v0/records")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"idempotency_key\": \"<string>\",\n \"source\": {\n \"corpus_id\": \"<string>\",\n \"namespace\": \"<string>\",\n \"record_key\": \"<string>\"\n },\n \"content\": {\n \"kind\": \"text\",\n \"text\": \"<string>\"\n },\n \"source_revision\": \"<string>\",\n \"source_position\": \"<string>\",\n \"extensions\": {},\n \"provenance\": {\n \"source_blob_ids\": [\n \"<string>\"\n ],\n \"producer\": \"<string>\",\n \"producer_version\": \"<string>\"\n }\n}"
response = http.request(request)
puts response.read_body{
"receipt_id": "<string>",
"state": "pending",
"diagnostics": [
{
"code": "<string>",
"message": "<string>",
"retryable": true,
"field": "<string>",
"resync_url": "<string>"
}
],
"source": {
"corpus_id": "<string>",
"namespace": "<string>",
"record_key": "<string>"
},
"processing": {
"state": "queued",
"phase": "materialization",
"message": "<string>"
},
"outcome": "created",
"record_id": "<string>",
"version_id": "<string>",
"availability": {
"state": "materialized",
"is_current": true,
"searchable": true
}
}{
"code": "<string>",
"message": "<string>",
"retryable": true,
"field": "<string>",
"resync_url": "<string>"
}Authorizations
API key, not necessarily a JWT. Server derives Organization, permitted actions and Corpus scope; every resource access is authorized.
Body
Initial request shape. Same source identity creates or corrects a Record. Same external revision with different canonical content conflicts. No revision means canonical Manifest digest identity; no source position means durable acceptance order. Single and batch entry replay share route_family=ingestion. A blob content accepts a verified text/* Blob, read at acceptance, or a Blob whose media type the installation routes to an external normalizer; that normalizer runs after acceptance and its output is the published Manifest, while the Version identity still derives from the submitted Blob. When the normalizer fails, the Version is quarantined with a Diagnostic on the Version read (or, on an optional text/* route, published through the built-in text path with provenance.normalization.fallback). Other media types are rejected with unverified_blob. provenance.normalization is engine-owned and rejected on input. Extension namespaces owned by the pinned plugin are written only by its normalizer output, published on the Version; a submission writing one, top-level or on a Part, is rejected with 422 extension_namespace_owned.
1Show child attributes
Show child attributes
- Option 1
- Option 2
- Option 3
Show child attributes
Show child attributes
1Optional monotonic source position, encoded as decimal text to avoid JSON numeric precision loss.
^[0-9]+$Keys are plugin namespaces. Data is validated against the installed schema version; source data is not a computed Annotation.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Response
Successful response
Durable acceptance outcome, not workflow state. Availability is a separate authorized live read view; omitted before a linked version exists. Infrastructure retry never resolves a Receipt as failed.
1pending, resolved 20Show child attributes
Show child attributes
Show child attributes
Show child attributes
Live read view, not a Receipt lifecycle or public workflow identifier. blocked means an outstanding contribution needs intervention; diagnostics describe why. idle means no work currently pending, not a promise of final enrichment. Phase is omitted when idle; required and optional progress do not override Version Availability.
Show child attributes
Show child attributes
created, duplicate, withdrawal_applied, conflict 11Show child attributes
Show child attributes