These endpoints cover your profile (GET and PATCH /profile, plus the avatar), your icon library (/icons), and URL previews (POST /opengraph). Icons are capped at 200 KB on every plan and accept png, jpg, gif, webp, and svg. OpenGraph fetches only public http and https URLs.

Profile

Get Profile

GET /api/v1/profile
curl https://app.opalrecall.com/api/v1/profile \
  -H "Authorization: Bearer opal_live_xxx"

Returns { "data": { displayName, email, avatarUrl, userType, emailNotifications } }. userType is the plan ID.

Update Profile

PATCH /api/v1/profile
curl -X PATCH https://app.opalrecall.com/api/v1/profile \
  -H "Authorization: Bearer opal_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{"displayName":"New display name","emailNotifications":false}'

Returns the updated profile fields under data. To read more about your profile in the app, see Set Up Your Opal Profile.

Avatar

Upload Avatar

POST /api/v1/profile/avatar

This is a multipart upload, and the first uploaded file is used, whatever its field name. Plan file-size and storage limits apply. Returns the updated user record under data.

Remove Avatar

DELETE /api/v1/profile/avatar

Deletes the current avatar file when it is in your storage and clears the avatar fields.

Icon Library

The icon library is your icons/ folder in Opal’s storage. It also lists older profile photos and workspace icons stored in your folder.

List Icons

GET /api/v1/icons

Returns { "data": [...], "listFailed": false }. Each entry has name, url, sizeBytes, contentType, lastModified, and source (icons, profile-legacy, or workspace-legacy). If the storage folder cannot be listed, listFailed is true and the legacy entries are still returned.

Upload Icon

POST /api/v1/icons
curl -X POST https://app.opalrecall.com/api/v1/icons \
  -H "Authorization: Bearer opal_live_xxx" \
  -F "file=@icon.png"

Multipart upload. The first uploaded file is used. Accepted types: png, jpg/jpeg, gif, webp, and svg (415 otherwise). SVGs are sanitized. Icons are capped at 200 KB on every plan (413) and count toward storage. Returns { "data": { name, url, size, type, originalName } }. Use name as itemIcon with itemIconType: "image".

Delete Icon

DELETE /api/v1/icons/:blobName

blobName must be URL-encoded. The file must be in your own folder (403 otherwise). Deleting clears the icon from your avatar, your workspace icons, and your item icons, so no broken references remain. Returns { "success": true }.

OpenGraph URL Preview

POST /api/v1/opengraph
curl -X POST https://app.opalrecall.com/api/v1/opengraph \
  -H "Authorization: Bearer opal_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/article"}'

Returns { "data": { "title", "description", "image", "url" } } from the page’s OpenGraph tags, falling back to its <title> and meta description.

  • Only http and https URLs are fetched.
  • URLs whose host is, or resolves to, a private, loopback, link-local, or other non-public address, or that redirect to one, return 400 Invalid or blocked URL.
  • Up to 5 redirects are followed.
  • Pages are fetched with a 10-second timeout and a 5 MB size cap.

Next Steps

FAQ

What is the icon size limit?

200 KB on every plan. A larger icon returns 413. Icons count toward your storage.

Which image types can I use as icons?

png, jpg/jpeg, gif, webp, and svg. Other types return 415. SVGs are sanitized.

How do I use an uploaded icon on an item?

Upload it with POST /icons, then use the returned name as itemIcon with itemIconType: "image" when you create or update the item.

Why does OpenGraph return Invalid or blocked URL?

Only public http and https URLs are fetched. A URL that points to, or redirects to, a private, loopback, or link-local address is blocked.