Memories
Create Apple Note revisions and read the complete current Memory projection.
GET /memories/:id
Returns one Memory owned by the authenticated Sterling Trace account.
1curl \
2 --request GET \
3 --url "https://accounts.sterlingtrace.com/developer/v1/memories/7b4f5c42-7f27-4f38-9f53-524b7e574d51" \
4 --header "Authorization: Bearer $TRACE_API_KEY"1const response = await fetch(
2 "https://accounts.sterlingtrace.com/developer/v1/memories/7b4f5c42-7f27-4f38-9f53-524b7e574d51",
3 {
4 headers: {
5 Authorization: `Bearer ${process.env.TRACE_API_KEY}`,
6 },
7 },
8);
9
10if (!response.ok) throw new Error(`Trace returned ${response.status}`);
11const { memory } = await response.json();1import os
2import requests
3
4response = requests.get(
5 "https://accounts.sterlingtrace.com/developer/v1/memories/7b4f5c42-7f27-4f38-9f53-524b7e574d51",
6 headers={"Authorization": f"Bearer {os.environ['TRACE_API_KEY']}"},
7 timeout=10,
8)
9response.raise_for_status()
10memory = response.json()["memory"]| Name | Type | Required | Description |
|---|---|---|---|
id | UUID | Yes | The Memory ID supplied by a webhook or returned by creation. |
The projection includes the preserved metadata and every enrichment field currently available. A field may be null while its processing stage is incomplete or when the app cannot provide it.
GET response
{
"memory": {
"id": "7b4f5c42-7f27-4f38-9f53-524b7e574d51",
"createdAt": "2026-09-11T09:42:17.000Z",
"type": "email",
"source": "gmail",
"metadata": { "subject": "September software receipt" },
"canonicalText": "Receipt from Northstar Software…",
"description": "## Purchase\nAnnual software subscription…",
"gist": "Annual software subscription for £120 including VAT.",
"tags": ["receipt", "software"],
"questions": ["What software costs did the business incur?"],
"relevance": { "relevant": true, "score": 0.98, "provenance": "model" }
}
}Create an Apple Note Memory
POST /memories
Accepts one immutable revision from the Apple Notes desktop app. This endpoint currently accepts only type: "note" with memory.app: "apple-notes". The stored Memory is tagged apple-notes-app as a durable app fact, then follows the ordinary extraction, enrichment, graph and tag pipeline.
1curl \
2 --request POST \
3 --url "https://accounts.sterlingtrace.com/developer/v1/memories" \
4 --header "Authorization: Bearer $TRACE_API_KEY" \
5 --header "Content-Type: application/json" \
6 --data @apple-note.json1const response = await fetch(
2 "https://accounts.sterlingtrace.com/developer/v1/memories",
3 {
4 method: "POST",
5 headers: {
6 Authorization: `Bearer ${process.env.TRACE_API_KEY}`,
7 "Content-Type": "application/json",
8 },
9 body: JSON.stringify(appleNote),
10 },
11);
12
13if (!response.ok) throw new Error(`Trace returned ${response.status}`);
14const { memory, duplicate } = await response.json();1import os
2import requests
3
4response = requests.post(
5 "https://accounts.sterlingtrace.com/developer/v1/memories",
6 headers={"Authorization": f"Bearer {os.environ['TRACE_API_KEY']}"},
7 json=apple_note,
8 timeout=30,
9)
10response.raise_for_status()
11memory = response.json()["memory"]{
"type": "note",
"memory": {
"app": "apple-notes",
"id": "x-coredata://79E7DC60-5698-487A-999E-C79B44352DE6/ICNote/p5079",
"revisionId": "b3c7b3c7b3c7b3c7b3c7b3c7b3c7b3c7b3c7b3c7b3c7b3c7b3c7b3c7b3c7b3c7b3c7",
"previousRevisionId": null,
"title": "March plan",
"account": "iCloud",
"folder": null,
"createdAt": "2026-09-11T14:53:47Z",
"updatedAt": "2026-09-11T21:35:12Z",
"locked": false,
"content": "# March plan\n\nShip the developer API."
}
}id is the stable Apple Note ID. revisionId is the client-calculated 64-character hexadecimal SHA-256 identifier for the complete normalized note revision; retrying the same document returns the same Memory with duplicate: true. Do not edit an accepted revision. Send a changed note as a new request with a new revisionId and the preceding revision in previousRevisionId; Trace records a supersedes graph edge. The first revision sets previousRevisionId to null. content is limited to 2 MiB.
The desktop app should map its Markdown front matter to the camel-case fields above, convert a missing folder to null, and put the Markdown body in content. The request is accepted only after durable storage and a normal processing request is attempted; enrichment itself remains asynchronous.
Response
{ "memory": { "id": "7b4f5c42-7f27-4f38-9f53-524b7e574d51" }, "duplicate": false }201 means a new revision was accepted. 200 means an idempotent retry found the original revision. If starting the asynchronous worker is temporarily unavailable, Trace reports and recovers it through the normal sweep; the stored 201 result is still valid.
Errors
| Status | Error code | Meaning |
|---|---|---|
400 | invalid-request | The JSON does not match the Apple Note contract. |
401 | not-authenticated | The Bearer key is missing, malformed, expired or revoked. |
403 | developer-scope-required | The key lacks the required permission; grant memories:write in Developer settings to add a Memory. |
409 | revision-conflict | That revision ID was already used with different contents, or an initial revision conflicts with an existing note. |
409 | previous-revision-not-found | Send the missing predecessor first. |
500 | internal-error | Trace could not accept the request. Retry with backoff. |