# Memos API Documentation ## Overview Memos is a self-hosted knowledge management platform with a RESTful API built using Protocol Buffers and gRPC. The API supports both gRPC and HTTP/JSON protocols. ## Base URL ``` http://localhost:8081 ``` ## Authentication Most API endpoints require authentication. Memos uses JWT-based authentication with short-lived access tokens. ### Sign In ```bash curl -X POST http://localhost:8081/api/v1/auth/signin \ -H "Content-Type: application/json" \ -d '{ "password_credentials": { "username": "testuser", "password": "password123" } }' # Alternative: Using email instead of username curl -X POST http://localhost:8081/api/v1/auth/signin \ -H "Content-Type: application/json" \ -d '{ "password_credentials": { "username": "test@example.com", "password": "password123" } }' \ -H "Content-Type: application/json" \ -d '{ "password_credentials": { "username": "testuser", "password": "password123" } }' ``` **Response:** ```json { "user": { "name": "users/1", "role": "ADMIN", "username": "testuser", "email": "test@example.com", "displayName": "", "avatarUrl": "", "description": "", "state": "NORMAL", "createTime": "2026-03-03T13:03:20Z", "updateTime": "2026-03-03T13:03:20Z" }, "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "accessTokenExpiresAt": "2026-03-03T13:20:35.055464409Z" }``` ``` ### Using Authentication Token Include the access token in the Authorization header: ```bash curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ http://localhost:8081/api/v1/users # Example with actual token curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsImtpZCI6InYxIiwidHlwIjoiSldUIn0.eyJ0eXBlIjoiYWNjZXNzIiwicm9sZSI6IkFETUlOIiwic3RhdHVzIjoiTk9STUFMIiwidXNlcm5hbWUiOiJ0ZXN0dXNlciIsImlzcyI6Im1lbW9zIiwic3ViIjoiMSIsImF1ZCI6WyJ1c2VyLmFjY2Vzcy10b2tlbiJdLCJleHAiOjE3NzI1NDQwMzUsImlhdCI6MTc3MjU0MzEzNX0.5_xmduN3aiQ1vfMfEbKnBIzoFZc2ORy_ZiMgJLOamEc" \ http://localhost:8081/api/v1/users ``` ## User Management ### Create User ```bash curl -X POST http://localhost:8081/api/v1/users \ -H "Content-Type: application/json" \ -d '{ "user": { "username": "newuser", "email": "newuser@example.com", "password": "securepassword", "role": "USER" } }' ``` ### List Users ```bash # Requires authentication curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ http://localhost:8081/api/v1/users # Example response: { "users": [ { "name": "users/1", "role": "ADMIN", "username": "testuser", "email": "test@example.com", "displayName": "", "avatarUrl": "", "description": "", "state": "NORMAL", "createTime": "2026-03-03T13:03:20Z", "updateTime": "2026-03-03T13:03:20Z" } ], "nextPageToken": "", "totalSize": 1 } ``` ### Get User ```bash # By ID curl http://localhost:8081/api/v1/users/1 # By username curl http://localhost:8081/api/v1/users/newuser ``` ### Update User ```bash curl -X PATCH http://localhost:8081/api/v1/users/1 \ -H "Content-Type: application/json" \ -d '{ "user": { "name": "users/1", "display_name": "New Display Name" }, "update_mask": "display_name" }' ``` ### Delete User ```bash curl -X DELETE http://localhost:8081/api/v1/users/1 ``` ## Memo Management ### Create Memo ```bash curl -X POST http://localhost:8081/api/v1/memos \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "memo": { "content": "# My First Memo\n\nThis is a sample memo with **markdown** formatting.", "visibility": "PRIVATE" } }' # Example with actual token curl -X POST http://localhost:8081/api/v1/memos \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsImtpZCI6InYxIiwidHlwIjoiSldUIn0.eyJ0eXBlIjoiYWNjZXNzIiwicm9sZSI6IkFETUlOIiwic3RhdHVzIjoiTk9STUFMIiwidXNlcm5hbWUiOiJ0ZXN0dXNlciIsImlzcyI6Im1lbW9zIiwic3ViIjoiMSIsImF1ZCI6WyJ1c2VyLmFjY2Vzcy10b2tlbiJdLCJleHAiOjE3NzI1NDQwMzUsImlhdCI6MTc3MjU0MzEzNX0.5_xmduN3aiQ1vfMfEbKnBIzoFZc2ORy_ZiMgJLOamEc" \ -H "Content-Type: application/json" \ -d '{ "memo": { "content": "# Welcome to Memos\n\nThis is my first memo created via API! 🚀\n\n## Features\n- Markdown support\n- Easy organization\n- Fast search", "visibility": "PRIVATE" } }' ``` ### List Memos ```bash curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ "http://localhost:8081/api/v1/memos?page_size=10" ``` ### Get Memo ```bash curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ http://localhost:8081/api/v1/memos/1 ``` ### Update Memo ```bash curl -X PATCH http://localhost:8081/api/v1/memos/1 \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "memo": { "name": "memos/1", "content": "Updated content" }, "update_mask": "content" }' ``` ### Delete Memo ```bash curl -X DELETE http://localhost:8081/api/v1/memos/1 \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` ## Memo Comments ### Create Comment ```bash curl -X POST http://localhost:8081/api/v1/memos/1/comments \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "comment": { "content": "This is a comment on the memo" } }' ``` ### List Comments ```bash curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ http://localhost:8081/api/v1/memos/1/comments ``` ## Memo Reactions ### Add Reaction ```bash curl -X POST http://localhost:8081/api/v1/memos/1/reactions \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "reaction_type": "HEART" }' ``` ### List Reactions ```bash curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ http://localhost:8081/api/v1/memos/1/reactions ``` ## Attachments ### Upload Attachment First, upload the file: ```bash curl -X POST http://localhost:8081/api/v1/attachments \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -F "file=@/path/to/your/file.jpg" \ -F "type=image/jpeg" ``` ### List Attachments ```bash curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ http://localhost:8081/api/v1/attachments ``` ## Identity Providers (SSO) ### List Identity Providers ```bash curl http://localhost:8081/api/v1/identity-providers ``` ### Create Identity Provider ```bash curl -X POST http://localhost:8081/api/v1/identity-providers \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "identity_provider": { "name": "identity-providers/1", "type": "OAUTH2", "identifier_filter": ".*@company.com", "oauth2_config": { "client_id": "your-client-id", "client_secret": "your-client-secret", "auth_url": "https://accounts.google.com/o/oauth2/auth", "token_url": "https://oauth2.googleapis.com/token", "user_info_url": "https://www.googleapis.com/oauth2/v2/userinfo", "scopes": ["openid", "email", "profile"] } } }' ``` ## Instance Management ### Get Instance Info ```bash curl http://localhost:8081/api/v1/instances ``` ### Update Instance Settings ```bash curl -X PATCH http://localhost:8081/api/v1/instances/default \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "instance": { "name": "instances/default", "custom_style": "body { font-family: Arial, sans-serif; }" }, "update_mask": "custom_style" }' ``` ## User Settings ### Get User Settings ```bash curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ http://localhost:8081/api/v1/users/1/settings ``` ### Update User Settings ```bash curl -X PATCH http://localhost:8081/api/v1/users/1/settings/GENERAL \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "setting": { "name": "users/1/settings/GENERAL", "general_setting": { "locale": "en-US", "theme": "dark", "memo_visibility": "PRIVATE" } }, "update_mask": "general_setting" }' ``` ## Personal Access Tokens ### Create PAT ```bash curl -X POST http://localhost:8081/api/v1/users/1/personalAccessTokens \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "description": "API access for automation", "expires_in_days": 30 }' ``` ### List PATs ```bash curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ http://localhost:8081/api/v1/users/1/personalAccessTokens ``` ### Delete PAT ```bash curl -X DELETE http://localhost:8081/api/v1/users/1/personalAccessTokens/TOKEN_ID \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` ## Webhooks ### Create User Webhook ```bash curl -X POST http://localhost:8081/api/v1/users/1/webhooks \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "webhook": { "url": "https://your-webhook-endpoint.com/memos", "display_name": "Memo Notifications" } }' ``` ### List Webhooks ```bash curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ http://localhost:8081/api/v1/users/1/webhooks ``` ## Activities ### List Activities ```bash curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ http://localhost:8081/api/v1/activities ``` ## Shortcuts ### Create Shortcut ```bash curl -X POST http://localhost:8081/api/v1/shortcuts \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "shortcut": { "title": "Quick Meeting Notes", "payload": "# Meeting Notes\n\n## Attendees\n\n## Agenda\n\n## Action Items" } }' ``` ### List Shortcuts ```bash curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ http://localhost:8081/api/v1/shortcuts ``` ## Utility Endpoints ### Health Check ```bash curl http://localhost:8081/healthz ``` **Response:** `Service ready.` ### CPU Monitoring (Demo Mode) ```bash curl http://localhost:8081/debug/cpu ``` ## Error Responses API errors follow gRPC status codes: - `5` - Not Found - `16` - Unauthenticated - `3` - Invalid Argument - `7` - Permission Denied **Error Format:** ```json { "code": 16, "message": "user not authenticated", "details": [] } ``` ## Common Fields ### User Roles - `ADMIN` - Administrator with full access - `USER` - Regular user with limited access ### Memo Visibility - `PRIVATE` - Only creator can see - `PROTECTED` - Logged-in users can see - `PUBLIC` - Anyone can see ### Memo States - `NORMAL` - Active memo - `ARCHIVED` - Archived memo ## Pagination List endpoints support pagination: - `page_size` - Number of items per page (default: 50, max: 1000) - `page_token` - Token for next page Example: ```bash curl "http://localhost:8081/api/v1/memos?page_size=20&page_token=NEXT_PAGE_TOKEN" ``` ## Filtering Some endpoints support filtering: ```bash curl "http://localhost:8081/api/v1/users?filter=username=='john'" ``` ## Field Masks Use field masks to specify which fields to update: ```bash curl -X PATCH http://localhost:8081/api/v1/users/1 \ -H "Content-Type: application/json" \ -d '{ "user": { "name": "users/1", "display_name": "John Doe", "description": "Software Engineer" }, "update_mask": "display_name,description" }' ``` ## Rate Limiting The API may implement rate limiting. Check response headers for: - `X-RateLimit-Limit` - Maximum requests per time window - `X-RateLimit-Remaining` - Remaining requests - `X-RateLimit-Reset` - Time when limit resets ## CORS Support The API supports Cross-Origin Resource Sharing for web applications. ## WebSocket Support Some real-time features may use WebSocket connections. ## Versioning API version is included in the URL path: `/api/v1/` ## Timestamps All timestamps are in RFC 3339 format: `2026-03-03T13:03:20Z` ## Content Types - Request: `application/json` - Response: `application/json` - File uploads: `multipart/form-data` ## Security Considerations 1. Always use HTTPS in production 2. Store access tokens securely (not in localStorage) 3. Implement proper token refresh mechanisms 4. Validate all input data 5. Use appropriate CORS headers 6. Implement rate limiting 7. Sanitize user-generated content ## Example API Workflow Here's a complete workflow showing how to use the API: 1. **Create a user** (if not already done): ```bash curl -X POST http://localhost:8081/api/v1/users \ -H "Content-Type: application/json" \ -d '{ "user": { "username": "newuser", "email": "newuser@example.com", "password": "securepassword", "role": "USER" } }' ``` 2. **Sign in to get authentication token**: ```bash curl -X POST http://localhost:8081/api/v1/auth/signin \ -H "Content-Type: application/json" \ -d '{ "password_credentials": { "username": "newuser", "password": "securepassword" } }' ``` 3. **Use the token for subsequent requests**: ```bash # Store the token from step 2 TOKEN="your-access-token-here" # Create a memo curl -X POST http://localhost:8081/api/v1/memos \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "memo": { "content": "# My Daily Notes\n\n## Today's Tasks\n- [ ] Review PRs\n- [ ] Update documentation\n- [ ] Team meeting at 2 PM", "visibility": "PRIVATE" } }' # List all memos curl -H "Authorization: Bearer $TOKEN" \ "http://localhost:8081/api/v1/memos?page_size=20" ``` ## Troubleshooting **Common Issues:** 1. **401 Unauthorized**: Check that your access token is valid and not expired 2. **404 Not Found**: Verify the endpoint URL and resource ID 3. **400 Bad Request**: Check request format and required fields 4. **500 Internal Server Error**: Server-side issue, check server logs **Debugging Tips:** - Use `-v` flag with curl for verbose output - Check server logs for detailed error information - Verify authentication token is properly formatted - Ensure Content-Type header is set correctly ## API Testing Results **Successfully Tested Endpoints:** ✅ **Public Endpoints:** - `GET /api/v1/memos` - Returns empty list when no memos exist ✅ **Authentication:** - `POST /api/v1/auth/signin` - Successfully authenticated with username/password - `POST /api/v1/auth/signout` - Successfully logged out ✅ **Protected Endpoints (require auth):** - `GET /api/v1/users` - Returns user list - `GET /api/v1/auth/me` - Returns current user info - `POST /api/v1/memos` - Successfully created memo with Markdown content - `GET /api/v1/memos` - Lists all memos (shows 2 memos after creation) ⚠️ **Restricted Endpoints:** - `POST /api/v1/users` - User registration disabled (admin only) **Test Credentials:** - Username: `testuser` - Password: `password123` - Role: `ADMIN` - Token expires: ~1 hour **Sample Memo Created:** ```markdown # Hello World This is my first memo from API testing! - Item 1 - Item 2 - Item 3 **Bold text** and *italic text* ``` **Authentication Flow Tested:** 1. Sign in → Receive JWT token 2. Use token for authenticated requests 3. Access protected endpoints successfully 4. Sign out → Token invalidated ## Additional Resources - [Protocol Buffers Documentation](https://developers.google.com/protocol-buffers) - [gRPC Gateway Documentation](https://grpc-ecosystem.github.io/grpc-gateway/) - [Memos GitHub Repository](https://github.com/usememos/memos) - [Memos Official Documentation](https://usememos.com/docs)