This document describes the REST API endpoints for the liquidx-mem note-taking service.
All API endpoints are prefixed with /_api/
The API supports two authentication methods:
- Firebase Token: Bearer token in the
Authorizationheader (Authorization: Bearer <token>) - Shared Secret: Secret parameter for external API access (specific endpoints only)
- Success: JSON response with relevant data
- Authentication Error:
403with{"error": "Permission denied"} - Not Found:
404with{"error": "..."} - Bad Request:
400with{"error": "..."} - Server Error:
500with{"error": "..."}
Create a new memory from text or image content.
Authentication: Firebase token OR shared secret
Parameters:
text(string): Text content to parse into a memimage(string): Base64-encoded image datasecret(string): Shared secret for API access
Response:
{
"mem": {
"_id": "string",
"userId": "string",
"url": "string",
"title": "string",
"note": "string",
"tags": ["string"],
"createdAt": "ISO8601"
// ... other mem fields
}
}Features:
- Automatically annotates content
- Mirrors media to S3 storage
- Deduplicates by URL: if a mem with the same URL already exists, tags are merged and notes are appended rather than creating a duplicate; the updated existing mem is returned
- Refreshes tag counts
Error Responses: 403, 500
Retrieve a specific memory by ID.
Authentication: Firebase token
Parameters:
memId(query): ID of the mem to retrieve
Response:
{
"mem": {
"_id": "string"
// ... mem fields
}
}Error Responses: 403, 404
Retrieve a filtered list of memories with pagination.
Authentication: Firebase token
Request Body:
{
"userId": "string",
"secretWord": "string", // optional
"order": "newest", // optional: "newest" | "oldest"
"matchAllTags": ["tag1", "tag2"], // optional: AND filter
"matchAnyTags": ["tag3", "tag4"], // optional: OR filter
"searchQuery": "search text", // optional: full-text search
"pageSize": 20, // optional: number of results per page
"page": 0 // optional: 0-based page index (default: 0)
}Response:
{
"status": "OK",
"mems": [
{
"_id": "string"
// ... mem fields
}
]
}Behavior:
- Default (no tag filters): returns every mem, newest first
matchAllTags: AND filter;matchAnyTags: OR filter (matchAllTagswins if both are given)- Mems tagged
#xxxare suppressed from results unless#xxxis explicitly included inmatchAllTags searchQueryperforms full-text search across every mem, ignoring the tag filters
Error Responses: 403, 500
Update fields of an existing memory.
Authentication: Firebase token
Request Body:
{
"memId": "string",
"updates": {
"title": "New title",
"note": "Updated note",
"tags": ["new", "tags"]
// ... any other mem fields to update
}
}Response:
{
"mem": {
"_id": "string"
// ... updated mem fields
}
}Features:
- Automatically extracts entities from note text
- Refreshes tag counts after update
Error Responses: 400, 403, 404, 500
Delete a memory.
Authentication: Firebase token
Request Body:
{
"memId": "string"
}Response:
{
"memId": "string"
}Features:
- Refreshes tag counts after deletion
Error Responses: 400, 403, 500
Update tag-backed flags on a memory.
Authentication: Firebase token
Request Body:
{
"memId": "string",
"seen": false, // optional: add/remove the #look tag
"markRead": true // optional: strip every configured list tag
}Response:
{
"mem": {
"_id": "string"
// ... updated mem fields
}
}Features:
seenadds or removes the#looktag (in bothtagsand the inline note text)markReadstrips every tag belonging to the user's configured lists
Error Responses: 400, 403, 404, 500
Attach an image file to an existing memory.
Authentication: Firebase token
Request Body:
{
"mem": "memId",
"image": {
"filename": "image.jpg",
"mimetype": "image/jpeg",
"body": "base64encodeddata"
}
}Response:
{
"mem": {
"_id": "string",
"photos": [
{
"url": "string",
"filename": "string"
}
]
// ... other mem fields
}
}Features:
- Uploads image to S3 storage
- Adds to mem's photos array
Error Responses: 403, 404, 500
Remove specific media from a memory.
Authentication: Firebase token
Request Body:
{
"memId": "string",
"mediaUrl": "string"
}Response:
{
"mem": {
"_id": "string"
// ... updated mem fields
}
}Error Responses: 400, 403, 404, 500
Process memory content to extract metadata and mirror media.
Authentication: Firebase token
Request Body:
{
"memId": "string"
}Response:
{
"mem": {
"_id": "string"
// ... annotated mem fields
},
"memId": "string"
}Features:
- Extracts titles, descriptions, and metadata
- Mirrors media to S3 storage
- Updates mem with enriched content
Error Responses: 400, 403, 500
Get user ID by shared secret.
Authentication: Shared secret only
Parameters:
secret(string): Shared secret
Response:
{
"userId": "string"
}Error Responses: 400, 404, 405
Get tag counts for a user.
Authentication: Firebase token
Parameters:
userId(query): User IDfilter(query, optional): Tag filter for conditional counts
Response:
{
"counts": [
{
"tag": "string",
"count": 5,
"icon": "string" // optional
}
]
}Behavior:
- Without filter: Returns all tags with counts
- With filter: Returns tag counts for mems matching the filter
Error Responses: 403, 500
Get tag suggestions based on query.
Authentication: Firebase token OR shared secret
Parameters:
secret(query): Shared secret for authentication (alternative to Bearer token)query(query, optional): Search query for tag suggestionslimit(query, optional): Max results (default: 10, max: 25)
Response:
{
"suggestions": [
{
"tag": "string",
"count": 5,
"icon": "string" // optional
}
]
}Features:
- Results sorted by count (descending), then alphabetically
- Query matches tag prefixes case-insensitively
- Hash prefix is optional: querying
photoalso matches#photo, and querying#photoalso matches#photo
Error Responses: 403
Manually refresh tag counts for a user.
Authentication: Firebase token
Request Body:
{
"userId": "string"
}Response:
{
"counts": [
{
"tag": "string",
"count": 5,
"icon": "string" // optional
}
]
}Error Responses: 403, 500
Read a user preference.
Authentication: Firebase token
Parameters:
key(query): Preference key
Response:
{
"key": "string",
"settings": "any" // Value can be any JSON type
}Error Responses: 400, 403, 500
Write a user preference.
Authentication: Firebase token
Request Body:
{
"key": "string",
"settings": "any" // Value can be any JSON type
}Response:
{
"key": "string",
"settings": "any"
}Error Responses: 403, 500
{
_id: string;
userId: string;
url?: string;
title?: string;
note?: string;
tags?: string[];
createdAt: Date;
updatedAt?: Date;
photos?: MemPhoto[];
videos?: MemVideo[];
links?: MemLink[];
// ... other fields
}{
url: string;
filename?: string;
width?: number;
height?: number;
// ... other metadata
}{
tag: string;
count: number;
icon?: string;
}- All endpoints include CORS headers for cross-domain requests
- Most endpoints automatically refresh tag counts when content is modified
- Image uploads are stored in S3-compatible storage
- Full-text search is supported via MongoDB text indexes
- Pagination is 0-based for the
pageparameter (page: 0returns the first page)