Skip to content

Instantly share code, notes, and snippets.

@wayanjimmy
Created February 18, 2026 01:16
Show Gist options
  • Select an option

  • Save wayanjimmy/f8b8a1b9fd5562dbded9c7d1ba557574 to your computer and use it in GitHub Desktop.

Select an option

Save wayanjimmy/f8b8a1b9fd5562dbded9c7d1ba557574 to your computer and use it in GitHub Desktop.
Comprehensive Memos REST API Documentation - How to interact with the usememos/memos API

Memos REST API Documentation

Comprehensive guide for interacting with the Memos REST API
Generated from usememos/dotcom and usememos/memos


Table of Contents


Overview

Memos provides a comprehensive REST API for managing memos, users, attachments, and more. The API follows RESTful principles with resource-oriented URLs, standard HTTP methods, and JSON request/response bodies.

Key Features

  • RESTful Design: Standard HTTP methods (GET, POST, PATCH, DELETE)
  • Google AIP Compliance: Follows Google API Improvement Proposals for pagination, filtering, and field masks
  • Multiple Authentication Methods: Password, SSO, and Personal Access Tokens
  • Webhook Support: Real-time event notifications
  • CEL Filtering: Powerful filter expressions for list operations

Base URL

All API endpoints are prefixed with /api/v1:

https://your-memos-instance.com/api/v1

Demo Server

For testing purposes, you can use the demo server:

https://demo.usememos.com/api/v1

Authentication

The Memos API supports multiple authentication methods:

Bearer Token Authentication

For most endpoints, include the access token in the Authorization header:

Authorization: Bearer <your-access-token>

Password Authentication

Authenticate with username and password to receive access and refresh tokens.

Endpoint: POST /api/v1/auth/signin

Request Body:

{
  "passwordCredentials": {
    "username": "your-username",
    "password": "your-password"
  }
}

Response:

{
  "user": {
    "name": "users/123",
    "role": "USER",
    "username": "johndoe",
    "email": "john@example.com",
    "state": "NORMAL"
  },
  "accessToken": "eyJhbGciOiJIUzI1NiIs...",
  "accessTokenExpiresAt": "2026-02-18T12:00:00Z"
}

Notes:

  • The refresh token is automatically set as an HttpOnly cookie
  • The access token is short-lived (expires quickly)
  • Use the refresh token endpoint to get a new access token

SSO Authentication

Authenticate via an Identity Provider (IdP) using OAuth/OIDC.

Request Body:

{
  "ssoCredentials": {
    "idpId": 1,
    "code": "authorization-code-from-idp",
    "redirectUri": "https://your-app.com/callback",
    "codeVerifier": "pkce-code-verifier"  // Optional, for PKCE
  }
}

Personal Access Tokens (PATs)

PATs are long-lived tokens perfect for scripts and API integrations.

Creating a PAT

Endpoint: POST /api/v1/users/{user}/personalAccessTokens

Request Body:

{
  "parent": "users/123",
  "description": "My API integration",
  "expiresInDays": 365
}

Response:

{
  "personalAccessToken": {
    "name": "users/123/personalAccessTokens/abc123",
    "description": "My API integration",
    "createTime": "2026-02-18T00:00:00Z"
  },
  "token": "mtr_xxxxxxxxxxxxxxxx"  // Only shown once!
}

Important: The token value is only returned once at creation. Store it securely!

Using a PAT

Authorization: Bearer mtr_xxxxxxxxxxxxxxxx

Listing PATs

Endpoint: GET /api/v1/users/{user}/personalAccessTokens

Deleting a PAT

Endpoint: DELETE /api/v1/users/{user}/personalAccessTokens/{token}

Refresh Tokens

When your access token expires, use the refresh token to get a new one.

Endpoint: POST /api/v1/auth/refresh

  • The refresh token is automatically read from the HttpOnly cookie
  • Returns a new access token

Response:

{
  "accessToken": "eyJhbGciOiJIUzI1NiIs...",
  "accessTokenExpiresAt": "2026-02-18T13:00:00Z"
}

Get Current User

Verify your authentication and get user details.

Endpoint: GET /api/v1/auth/me

Equivalent to OIDC's /userinfo endpoint.

Response:

{
  "user": {
    "name": "users/123",
    "username": "johndoe",
    "role": "USER"
  }
}

Sign Out

Endpoint: POST /api/v1/auth/signout

Invalidates the current session and refresh token.


API Services

Auth Service

Method Endpoint Description
POST /api/v1/auth/signin Authenticate with credentials
POST /api/v1/auth/signout Sign out current user
GET /api/v1/auth/me Get current user info
POST /api/v1/auth/refresh Refresh access token

User Service

Method Endpoint Description
GET /api/v1/users List users
POST /api/v1/users Create user
GET /api/v1/users/{user} Get user
PATCH /api/v1/users/{user} Update user
DELETE /api/v1/users/{user} Delete user
GET /api/v1/users/{user}/settings List user settings
GET /api/v1/users/{user}/settings/{setting} Get user setting
PATCH /api/v1/users/{user}/settings/{setting} Update user setting
GET /api/v1/users/{user}/stats Get user stats
GET /api/v1/users:stats List all user stats
GET /api/v1/users/{user}/personalAccessTokens List PATs
POST /api/v1/users/{user}/personalAccessTokens Create PAT
DELETE /api/v1/users/{user}/personalAccessTokens/{token} Delete PAT
GET /api/v1/users/{user}/notifications List notifications
PATCH /api/v1/users/{user}/notifications/{notification} Update notification
DELETE /api/v1/users/{user}/notifications/{notification} Delete notification
GET /api/v1/users/{user}/webhooks List webhooks
POST /api/v1/users/{user}/webhooks Create webhook
PATCH /api/v1/users/{user}/webhooks/{webhook} Update webhook
DELETE /api/v1/users/{user}/webhooks/{webhook} Delete webhook

User Schema

{
  "name": "users/123",
  "role": "USER",  // ADMIN, USER
  "username": "johndoe",
  "email": "john@example.com",
  "displayName": "John Doe",
  "avatarUrl": "https://...",
  "description": "Bio here",
  "state": "NORMAL",  // NORMAL, ARCHIVED
  "createTime": "2026-01-01T00:00:00Z",
  "updateTime": "2026-02-01T00:00:00Z"
}

Memo Service

The core service for managing memos (notes).

Method Endpoint Description
GET /api/v1/memos List memos
POST /api/v1/memos Create memo
GET /api/v1/memos/{memo} Get memo
PATCH /api/v1/memos/{memo} Update memo
DELETE /api/v1/memos/{memo} Delete memo
GET /api/v1/memos/{memo}/comments List comments
POST /api/v1/memos/{memo}/comments Create comment
GET /api/v1/memos/{memo}/attachments List attachments
PATCH /api/v1/memos/{memo}/attachments Set attachments
GET /api/v1/memos/{memo}/relations List relations
PATCH /api/v1/memos/{memo}/relations Set relations
GET /api/v1/memos/{memo}/reactions List reactions
POST /api/v1/memos/{memo}/reactions Add reaction
DELETE /api/v1/memos/{memo}/reactions/{reaction} Delete reaction

Memo Schema

{
  "name": "memos/abc123",
  "state": "NORMAL",  // NORMAL, ARCHIVED
  "creator": "users/123",
  "createTime": "2026-02-18T00:00:00Z",
  "updateTime": "2026-02-18T01:00:00Z",
  "displayTime": "2026-02-18T00:00:00Z",
  "content": "# My Memo\n\nThis is content in **Markdown**.",
  "visibility": "PRIVATE",  // PRIVATE, PROTECTED, PUBLIC
  "tags": ["tag1", "tag2"],
  "pinned": false,
  "attachments": [],
  "relations": [],
  "reactions": [],
  "snippet": "My Memo This is content in Markdown.",
  "parent": "memos/parent123"
}

Creating a Memo

Endpoint: POST /api/v1/memos

Query Parameters:

  • memoId (optional): Specify a custom memo ID

Request Body:

{
  "content": "# Hello World\n\nMy first memo!",
  "visibility": "PRIVATE",
  "state": "NORMAL"
}

Listing Memos

Endpoint: GET /api/v1/memos

Query Parameters:

  • pageSize (int): Maximum items to return (default: 50, max: 1000)
  • pageToken (string): Pagination token from previous response
  • filter (string): CEL filter expression
  • orderBy (string): Sort order (e.g., "display_time desc")
  • state (enum): Filter by state (NORMAL, ARCHIVED)

Example with Filter:

GET /api/v1/memos?filter=visibility=="PUBLIC"&orderBy=create_time desc&pageSize=10

Updating a Memo

Endpoint: PATCH /api/v1/memos/{memo}?updateMask=content,visibility

The updateMask query parameter is required and specifies which fields to update.

Request Body:

{
  "content": "Updated content",
  "visibility": "PUBLIC"
}

Attachment Service

Manage file attachments.

Method Endpoint Description
GET /api/v1/attachments List attachments
POST /api/v1/attachments Create/upload attachment
GET /api/v1/attachments/{attachment} Get attachment
PATCH /api/v1/attachments/{attachment} Update attachment
DELETE /api/v1/attachments/{attachment} Delete attachment

Filter Examples:

filename.contains("test")
mime_type=="image/png"
create_time>"2026-01-01"

Activity Service

Track user activities.

Method Endpoint Description
GET /api/v1/activities List activities
GET /api/v1/activities/{activity} Get activity

Instance Service

Manage instance-wide settings.

Method Endpoint Description
GET /api/v1/instance/profile Get instance profile
GET /api/v1/instance/settings/{setting} Get instance setting
PATCH /api/v1/instance/settings/{setting} Update instance setting

Identity Provider Service

Manage SSO identity providers (admin only).

Method Endpoint Description
GET /api/v1/identity-providers List IdPs
POST /api/v1/identity-providers Create IdP
GET /api/v1/identity-providers/{id} Get IdP
PATCH /api/v1/identity-providers/{id} Update IdP
DELETE /api/v1/identity-providers/{id} Delete IdP

Shortcut Service

Manage user shortcuts.

Method Endpoint Description
GET /api/v1/users/{user}/shortcuts List shortcuts
POST /api/v1/users/{user}/shortcuts Create shortcut
GET /api/v1/users/{user}/shortcuts/{shortcut} Get shortcut
PATCH /api/v1/users/{user}/shortcuts/{shortcut} Update shortcut
DELETE /api/v1/users/{user}/shortcuts/{shortcut} Delete shortcut

Common Patterns

Pagination

List endpoints support cursor-based pagination using pageSize and pageToken:

Request:

GET /api/v1/memos?pageSize=10

Response:

{
  "memos": [...],
  "nextPageToken": "eyJwYWdlIjoyfQ=="
}

Next Request:

GET /api/v1/memos?pageSize=10&pageToken=eyJwYWdlIjoyfQ==

Limits:

  • Default page size: 50 (varies by endpoint)
  • Maximum page size: 1000

Filtering

List endpoints support CEL (Common Expression Language) filtering following Google AIP-160.

Operators:

  • == (equals)
  • != (not equals)
  • <, <=, >, >= (comparison)
  • : (contains)
  • in (membership)

Examples:

# Filter memos by visibility
visibility == "PUBLIC"

# Filter attachments by MIME type
mime_type == "image/png"

# Filter users by username
username == 'johndoe'

# Filter by partial match
filename.contains("test")

# Combined filters
visibility == "PUBLIC" && create_time > "2026-01-01"

Sorting

Use the orderBy parameter to sort results:

Examples:

# Single field
orderBy=create_time desc

# Multiple fields
orderBy=pinned desc, display_time desc

# Memo fields
orderBy=create_time asc
orderBy=update_time desc
orderBy=display_time desc

Field Masks

PATCH operations use field masks to specify which fields to update.

Format: Comma-separated field paths

Examples:

# Update single field
PATCH /api/v1/memos/abc123?updateMask=content

# Update multiple fields
PATCH /api/v1/memos/abc123?updateMask=content,visibility

# Update user settings
PATCH /api/v1/users/123/settings/locale?updateMask=value

Error Handling

The API returns standard HTTP status codes and JSON error responses.

Error Response Schema

{
  "code": 3,
  "message": "Invalid argument: visibility is required",
  "details": []
}

HTTP Status Codes

Code Meaning
200 Success
400 Bad Request - Invalid input
401 Unauthorized - Authentication required
403 Forbidden - Insufficient permissions
404 Not Found - Resource doesn't exist
409 Conflict - Resource already exists
500 Internal Server Error

Common Error Codes (Google RPC)

Code Name Description
0 OK Success
1 CANCELLED Operation cancelled
2 UNKNOWN Unknown error
3 INVALID_ARGUMENT Invalid request parameter
4 DEADLINE_EXCEEDED Request timeout
5 NOT_FOUND Resource not found
6 ALREADY_EXISTS Resource already exists
7 PERMISSION_DENIED Insufficient permissions
16 UNAUTHENTICATED Authentication required

Code Examples

cURL Examples

Sign In

curl -X POST https://demo.usememos.com/api/v1/auth/signin \
  -H "Content-Type: application/json" \
  -d '{
    "passwordCredentials": {
      "username": "your-username",
      "password": "your-password"
    }
  }'

Create a Memo

curl -X POST https://demo.usememos.com/api/v1/memos \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "# Hello from API\n\nThis is my memo!",
    "visibility": "PRIVATE",
    "state": "NORMAL"
  }'

List Memos with Filter

curl "https://demo.usememos.com/api/v1/memos?filter=visibility==%22PUBLIC%22&pageSize=10" \
  -H "Authorization: Bearer YOUR_TOKEN"

Update a Memo

curl -X PATCH "https://demo.usememos.com/api/v1/memos/abc123?updateMask=content" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Updated content!"
  }'

Python Example

import requests

BASE_URL = "https://demo.usememos.com/api/v1"

def sign_in(username, password):
    response = requests.post(f"{BASE_URL}/auth/signin", json={
        "passwordCredentials": {
            "username": username,
            "password": password
        }
    })
    return response.json()["accessToken"]

def create_memo(token, content, visibility="PRIVATE"):
    response = requests.post(
        f"{BASE_URL}/memos",
        headers={"Authorization": f"Bearer {token}"},
        json={
            "content": content,
            "visibility": visibility,
            "state": "NORMAL"
        }
    )
    return response.json()

def list_memos(token, filter_expr=None):
    params = {"pageSize": 50}
    if filter_expr:
        params["filter"] = filter_expr
    
    response = requests.get(
        f"{BASE_URL}/memos",
        headers={"Authorization": f"Bearer {token}"},
        params=params
    )
    return response.json()

# Usage
token = sign_in("your-username", "your-password")
memo = create_memo(token, "# Hello World\n\nMy first API memo!")
memos = list_memos(token, 'visibility=="PUBLIC"')

JavaScript/Node.js Example

const BASE_URL = 'https://demo.usememos.com/api/v1';

async function signIn(username, password) {
  const response = await fetch(`${BASE_URL}/auth/signin`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      passwordCredentials: { username, password }
    })
  });
  const data = await response.json();
  return data.accessToken;
}

async function createMemo(token, content, visibility = 'PRIVATE') {
  const response = await fetch(`${BASE_URL}/memos`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      content,
      visibility,
      state: 'NORMAL'
    })
  });
  return response.json();
}

async function listMemos(token, filter) {
  const params = new URLSearchParams({ pageSize: '50' });
  if (filter) params.append('filter', filter);
  
  const response = await fetch(`${BASE_URL}/memos?${params}`, {
    headers: { 'Authorization': `Bearer ${token}` }
  });
  return response.json();
}

// Usage
const token = await signIn('your-username', 'your-password');
const memo = await createMemo(token, '# Hello World!');
const memos = await listMemos(token, 'visibility=="PUBLIC"');

Webhook Integration

Webhooks allow you to receive real-time notifications when events occur.

Webhook Schema

{
  "name": "users/123/webhooks/abc123",
  "url": "https://your-app.com/webhook",
  "displayName": "My Webhook",
  "createTime": "2026-02-18T00:00:00Z",
  "updateTime": "2026-02-18T01:00:00Z"
}

Creating a Webhook

Endpoint: POST /api/v1/users/{user}/webhooks

Request Body:

{
  "url": "https://your-app.com/webhooks/memos",
  "displayName": "Production Webhook"
}

Updating a Webhook

Endpoint: PATCH /api/v1/users/{user}/webhooks/{webhook}?updateMask=url

Webhook Payload

When events occur, Memos will POST to your webhook URL with event data. The exact payload structure depends on the event type.

Security Note: Always verify webhook signatures when available, and use HTTPS endpoints.


Resources


This documentation was compiled from the Memos open-source project. For the latest updates, refer to the official repositories.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment