curl --disable --fail-with-body --request POST "${HYPERSPELL_API_URL}/memories/upload" \
--header "Authorization: Bearer $HYPERSPELL_API_KEY" \
--header "X-As-User: $HYPERSPELL_USER_ID" \
--form 'file=@notes.txt;type=text/plain' \
--form 'metadata={"collection":"project-notes"}'
import json
import os
import requests
with open("notes.txt", "rb") as file:
response = requests.post(
f"{os.environ['HYPERSPELL_API_URL']}/memories/upload",
headers={
"Authorization": f"Bearer {os.environ['HYPERSPELL_API_KEY']}",
"X-As-User": os.environ["HYPERSPELL_USER_ID"],
},
files={"file": ("notes.txt", file, "text/plain")},
data={"metadata": json.dumps({"collection": "project-notes"})},
)
response.raise_for_status()
print(response.json())
// Node.js 20+ (save as upload.mjs).
import { readFile } from "node:fs/promises";
const form = new FormData();
form.append("file", new Blob([await readFile("notes.txt")], { type: "text/plain" }), "notes.txt");
form.append("metadata", JSON.stringify({ collection: "project-notes" }));
const response = await fetch(`${process.env.HYPERSPELL_API_URL}/memories/upload`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.HYPERSPELL_API_KEY}`,
"X-As-User": process.env.HYPERSPELL_USER_ID,
},
body: form,
});
if (!response.ok) {
throw new Error(`Upload failed (${response.status}): ${await response.text()}`);
}
console.log(await response.json());
{
"source": "reddit",
"resource_id": "<string>",
"status": "pending"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Upload a file
This endpoint will upload a file to the index and return a resource_id.
The file will be processed in the background and the memory will be available for querying once the processing is complete.
You can use the resource_id to query the memory later, and check the status of the memory.
The examples upload a local notes.txt file for a specific user. Set these
environment variables before running them:
HYPERSPELL_API_URL: your API base URL, without a trailing slash. Usehttps://api.hyperspell.comfor US apps orhttps://api.eu.hyperspell.comfor EU apps. For a dedicated instance, use its API URL.HYPERSPELL_API_KEY: your API key.HYPERSPELL_USER_ID: the user who should own the uploaded memory.
The X-As-User header selects the user when using an app-wide key. With a
user-scoped key, omit this header or set it to that key’s user ID.
curl --disable --fail-with-body --request POST "${HYPERSPELL_API_URL}/memories/upload" \
--header "Authorization: Bearer $HYPERSPELL_API_KEY" \
--header "X-As-User: $HYPERSPELL_USER_ID" \
--form 'file=@notes.txt;type=text/plain' \
--form 'metadata={"collection":"project-notes"}'
import json
import os
import requests
with open("notes.txt", "rb") as file:
response = requests.post(
f"{os.environ['HYPERSPELL_API_URL']}/memories/upload",
headers={
"Authorization": f"Bearer {os.environ['HYPERSPELL_API_KEY']}",
"X-As-User": os.environ["HYPERSPELL_USER_ID"],
},
files={"file": ("notes.txt", file, "text/plain")},
data={"metadata": json.dumps({"collection": "project-notes"})},
)
response.raise_for_status()
print(response.json())
// Node.js 20+ (save as upload.mjs).
import { readFile } from "node:fs/promises";
const form = new FormData();
form.append("file", new Blob([await readFile("notes.txt")], { type: "text/plain" }), "notes.txt");
form.append("metadata", JSON.stringify({ collection: "project-notes" }));
const response = await fetch(`${process.env.HYPERSPELL_API_URL}/memories/upload`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.HYPERSPELL_API_KEY}`,
"X-As-User": process.env.HYPERSPELL_USER_ID,
},
body: form,
});
if (!response.ok) {
throw new Error(`Upload failed (${response.status}): ${await response.text()}`);
}
console.log(await response.json());
{
"source": "reddit",
"resource_id": "<string>",
"status": "pending"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}curl --disable --fail-with-body --request POST "${HYPERSPELL_API_URL}/memories/upload" \
--header "Authorization: Bearer $HYPERSPELL_API_KEY" \
--header "X-As-User: $HYPERSPELL_USER_ID" \
--form 'file=@notes.txt;type=text/plain' \
--form 'metadata={"collection":"project-notes"}'
import json
import os
import requests
with open("notes.txt", "rb") as file:
response = requests.post(
f"{os.environ['HYPERSPELL_API_URL']}/memories/upload",
headers={
"Authorization": f"Bearer {os.environ['HYPERSPELL_API_KEY']}",
"X-As-User": os.environ["HYPERSPELL_USER_ID"],
},
files={"file": ("notes.txt", file, "text/plain")},
data={"metadata": json.dumps({"collection": "project-notes"})},
)
response.raise_for_status()
print(response.json())
// Node.js 20+ (save as upload.mjs).
import { readFile } from "node:fs/promises";
const form = new FormData();
form.append("file", new Blob([await readFile("notes.txt")], { type: "text/plain" }), "notes.txt");
form.append("metadata", JSON.stringify({ collection: "project-notes" }));
const response = await fetch(`${process.env.HYPERSPELL_API_URL}/memories/upload`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.HYPERSPELL_API_KEY}`,
"X-As-User": process.env.HYPERSPELL_USER_ID,
},
body: form,
});
if (!response.ok) {
throw new Error(`Upload failed (${response.status}): ${await response.text()}`);
}
console.log(await response.json());
Authorizations
API Key or JWT User Token. If using an API Key, set the X-As-User header to act as a specific user. A JWT User Token is always scoped to a specific user.
Headers
Optionally set this header to act as a specific user when using an API Key, equivalent to first exchanging the API Key for a User Token
Body
The file to ingest.
The collection to add the document to — deprecated, set the collection using metadata instead.
Custom metadata as JSON string for filtering. Keys must be alphanumeric with underscores, max 64 chars. Values must be string, number, or boolean.
Response
Successful Response
reddit, notion, slack, google_calendar, google_mail, imap, google_meet, box, dropbox, github, gitlab, google_drive, vault, web_crawler, trace, microsoft_outlook, microsoft_teams, granola, fathom, fireflies, figma, linear, hubspot, salesforce, coda, confluence, jira, metabase, gong, clickup, lightfield, pylon, fellow, odoo, external_mcp pending, processing, completed, failed, pending_review, skipped, filtered, cancelled Was this page helpful?