RoamiROAMI

DEVELOPERS

API reference

Integrate directly against the Roami REST API. Defaults to the beta-scoped surface; switch to Full catalog for non-beta keys.

Showing the full catalog. Beta restrictions and draft-gating notes are hidden in this view.

Authentication

Base URL: https://api.roami.xyz

Send either header. Bearer tokens that start with sk_ are treated as API keys; other Bearer tokens are treated as session JWTs.

  • Authorization: Bearer sk_...
  • x-api-key: sk_...
curl 'https://api.roami.xyz/api/posts' \
  -H 'Authorization: Bearer sk_...'

Posts & Ideas

Create and update drafts, search content, manage ideas, and link related posts. Beta MCP tools: create_post, update_post, get_post, get_post_content, search_content, create_idea, get_idea, update_idea, link_related_posts.

GET/api/posts

List posts for the authenticated project.

Request: Optional query: status, search, limit, offset.

Response: { success, data: Post[] }

curl -X GET 'https://api.roami.xyz/api/posts?status=DRAFT&limit=20' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json'
POST/api/posts

Create a post (defaults to DRAFT).

Request: { title, slug?, content?, projectId, status? }

Response: { success, data: Post }

curl -X POST 'https://api.roami.xyz/api/posts' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json' \
  -d '{"title":"Notes from the road","projectId":"..."}'
GET/api/posts/:id

Fetch a post by id (includes blocks, tags, places when requested).

Response: { success, data: Post }

curl -X GET 'https://api.roami.xyz/api/posts/POST_ID' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json'
PUT/api/posts/:id

Update post fields; can set placeIds and related post links.

Request: { title?, content?, placeIds?, relatedPostIds?, ... }

Response: { success, data: Post }

curl -X PUT 'https://api.roami.xyz/api/posts/POST_ID' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json' \
  -d '{"title":"Updated title","relatedPostIds":["OTHER_ID"]}'
POST/api/posts/:id/publish

Publish a draft post.

Response: { success, data: Post } or 403 for beta keys

curl -X POST 'https://api.roami.xyz/api/posts/POST_ID/publish' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json'
POST/api/posts/:id/tags

Attach tags to a post (MCP: attach_tag_to_post).

Request: { tagIds: string[] }

Response: { success, data }

curl -X POST 'https://api.roami.xyz/api/posts/POST_ID/tags' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json' \
  -d '{"tagIds":["TAG_ID"]}'
GET/api/ideas

List ideas for the project.

Response: { success, data: Idea[] }

curl -X GET 'https://api.roami.xyz/api/ideas' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json'
POST/api/ideas

Create an idea.

Request: { title, description?, projectId }

Response: { success, data: Idea }

curl -X POST 'https://api.roami.xyz/api/ideas' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json' \
  -d '{"title":"Essay angle","projectId":"..."}'
GET/api/ideas/:id

Fetch one idea.

Response: { success, data: Idea }

curl -X GET 'https://api.roami.xyz/api/ideas/IDEA_ID' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json'
PUT/api/ideas/:id

Update an idea.

Request: { title?, description?, status? }

Response: { success, data: Idea }

curl -X PUT 'https://api.roami.xyz/api/ideas/IDEA_ID' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json' \
  -d '{"title":"Refined angle"}'

Media

Images, galleries, videos, and photo stories (reels). Beta MCP tools: list_images, update_image, list/create/update galleries, list/update videos, photo story CRUD + photo set helpers.

GET/api/media/images

List media library images.

Request: Optional query: search, folderId, limit.

Response: { success, data: Image[] }

curl -X GET 'https://api.roami.xyz/api/media/images?limit=50' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json'
PUT/api/media/images/:id

Update image metadata (title, alt, caption, GPS).

Request: { title?, altText?, caption?, latitude?, longitude? }

Response: { success, data: Image }

curl -X PUT 'https://api.roami.xyz/api/media/images/IMAGE_ID' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json' \
  -d '{"altText":"Sunrise over the ridge"}'
GET/api/galleries

List galleries.

Response: { success, data: Gallery[] }

curl -X GET 'https://api.roami.xyz/api/galleries' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json'
POST/api/galleries

Create a gallery.

Request: { title, projectId, description? }

Response: { success, data: Gallery }

curl -X POST 'https://api.roami.xyz/api/galleries' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json' \
  -d '{"title":"Coast road","projectId":"..."}'
PUT/api/galleries/:id

Update gallery metadata or membership.

Response: { success, data: Gallery }

curl -X PUT 'https://api.roami.xyz/api/galleries/GALLERY_ID' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json' \
  -d '{"title":"Coast road — edit"}'
GET/api/videos

List videos.

Response: { success, data: Video[] }

curl -X GET 'https://api.roami.xyz/api/videos' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json'
PUT/api/videos/:id

Update video metadata.

Response: { success, data: Video }

curl -X PUT 'https://api.roami.xyz/api/videos/VIDEO_ID' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json' \
  -d '{"title":"Market walk"}'
GET/api/reels

List photo stories (reels).

Response: { success, data: Reel[] }

curl -X GET 'https://api.roami.xyz/api/reels' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json'
POST/api/reels

Create a photo story.

Request: { title, projectId, ... }

Response: { success, data: Reel }

curl -X POST 'https://api.roami.xyz/api/reels' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json' \
  -d '{"title":"Weekend strip","projectId":"..."}'
GET/api/reels/:id

Fetch one photo story (MCP: get_photo_story).

Response: { success, data: Reel }

curl -X GET 'https://api.roami.xyz/api/reels/REEL_ID' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json'
PUT/api/reels/:id

Update photo story fields and photo membership.

Response: { success, data: Reel }

curl -X PUT 'https://api.roami.xyz/api/reels/REEL_ID' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json' \
  -d '{"title":"Weekend strip — v2"}'

Tags

Project-scoped taxonomy. Beta MCP tools: list_tags, create_tag, attach_tag_to_post.

GET/api/tags

List tags for the project.

Response: { success, data: Tag[] }

curl -X GET 'https://api.roami.xyz/api/tags' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json'
POST/api/tags

Create a tag.

Request: { name, projectId, slug? }

Response: { success, data: Tag }

curl -X POST 'https://api.roami.xyz/api/tags' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json' \
  -d '{"name":"slow-travel","projectId":"..."}'
DELETE/api/tags/:id

Delete a tag.

Response: { success }

curl -X DELETE 'https://api.roami.xyz/api/tags/TAG_ID' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json'

Places

Geographic places linked to posts. Beta MCP tools: search_places, create_place, link_post_places.

GET/api/places/search

Search places by name/region.

Request: Query: q (required).

Response: { success, data: Place[] }

curl -X GET 'https://api.roami.xyz/api/places/search?q=Chiang%20Mai' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json'
POST/api/places

Create a place.

Request: { name, country?, region?, latitude?, longitude?, projectId }

Response: { success, data: Place }

curl -X POST 'https://api.roami.xyz/api/places' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json' \
  -d '{"name":"Chiang Mai","country":"Thailand","projectId":"..."}'
PUT/api/posts/:id

Link places to a post via placeIds (MCP: link_post_places).

Request: { placeIds: string[] }

Response: { success, data: Post }

curl -X PUT 'https://api.roami.xyz/api/posts/POST_ID' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json' \
  -d '{"placeIds":["PLACE_ID"]}'

Trip Journal

Trip capture pipeline (logs → scaffold). Beta MCP tools: list_trip_journals, create_trip_journal, get_trip_journal, add_trip_journal_log, create_journal_entry.

GET/api/trip-journal/trips

List trip journals for the caller.

Response: { success, data: TripJournal[] }

curl -X GET 'https://api.roami.xyz/api/trip-journal/trips' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json'
POST/api/trip-journal/trips

Create a trip journal.

Request: { title, startDate?, endDate? }

Response: { success, data: TripJournal }

curl -X POST 'https://api.roami.xyz/api/trip-journal/trips' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json' \
  -d '{"title":"Leh road trip"}'
GET/api/trip-journal/trips/:id

Fetch one trip with logs.

Response: { success, data: TripJournal }

curl -X GET 'https://api.roami.xyz/api/trip-journal/trips/TRIP_ID' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json'
POST/api/trip-journal/trips/:id/logs

Add a log entry to a trip (MCP: add_trip_journal_log).

Request: { text, loggedAt?, placeName? }

Response: { success, data }

curl -X POST 'https://api.roami.xyz/api/trip-journal/trips/TRIP_ID/logs' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json' \
  -d '{"text":"Crossed the pass at 16:00"}'
POST/api/journals

Create a journal entry (MCP: create_journal_entry).

Request: { content, mood?, projectId, ... }

Response: { success, data: JournalEntry }

curl -X POST 'https://api.roami.xyz/api/journals' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json' \
  -d '{"content":"Quiet morning.","projectId":"..."}'

Hygiene (read-only)

Read-only SEO and media audits. Exposed as MCP tools (no dedicated REST routes). Beta allowlist includes both audit tools so partners can check drafts before CMS review.

MCP tools

audit_content_hygiene

Audit a post or landing page for metadata, internal links, places, media coverage, and block structure.

audit_media_hygiene

Audit image metadata (title, alt, caption, GPS) for a post, gallery, or project-wide.

Landing Pages

Curated destination hubs (LANDING_PAGE posts). Full-scope MCP tools only.

GET/api/landing-pages

List landing pages.

Response: { success, data }

curl -X GET 'https://api.roami.xyz/api/landing-pages' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json'
POST/api/landing-pages

Create a landing page.

Response: { success, data }

curl -X POST 'https://api.roami.xyz/api/landing-pages' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json' \
  -d '{"title":"Thailand slow travel","slug":"thailand"}'
PUT/api/landing-pages/:id

Update landing page fields.

Response: { success, data }

curl -X PUT 'https://api.roami.xyz/api/landing-pages/LP_ID' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json' \
  -d '{"title":"Thailand — updated"}'

Flight Routes

Scenic flight path content with landmarks and seat maps.

GET/api/flights

List flight routes.

Response: { success, data }

curl -X GET 'https://api.roami.xyz/api/flights' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json'
POST/api/flights

Create a flight route.

Response: { success, data }

curl -X POST 'https://api.roami.xyz/api/flights' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json' \
  -d '{"airline":"…","origin":"DEL","destination":"LEH"}'
PUT/api/flights/:id

Update a flight route.

Response: { success, data }

curl -X PUT 'https://api.roami.xyz/api/flights/FLIGHT_ID' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json' \
  -d '{"title":"…"}'

Newsletter

Campaigns, templates, segments, and send. Excluded from the beta MCP allowlist.

GET/api/newsletters/campaigns

List newsletter campaigns.

Response: { success, data }

curl -X GET 'https://api.roami.xyz/api/newsletters/campaigns' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json'
POST/api/newsletters/campaigns

Create a campaign.

Response: { success, data }

curl -X POST 'https://api.roami.xyz/api/newsletters/campaigns' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json' \
  -d '{"name":"Weekly","subject":"…"}'
POST/api/newsletters/campaigns/:id/send

Send a campaign (supports dryRun).

Request: { dryRun?, limit? }

Response: { success, data }

curl -X POST 'https://api.roami.xyz/api/newsletters/campaigns/CAMPAIGN_ID/send' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json' \
  -d '{"dryRun":true}'

Content / Media Hygiene

Mutating hygiene tools (MCP). Read-only audits are available to beta; fixes are full-scope only.

MCP tools

fix_content_metadata

Apply metadata hygiene fixes to a post (supports dry-run).

fix_content_relations

Update relation arrays (tags, places, related posts, media) for linking quality.

bulk_fix_media_hygiene

Batch update image metadata fields; supports dry-run planning.

API Key Management

Mint and revoke keys via authenticated CMS session. Excluded from beta MCP — no agent-side key minting without human oversight.

GET/api/api-keys

List API keys for the account/project.

Response: { success, data }

curl -X GET 'https://api.roami.xyz/api/api-keys' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json'
POST/api/api-keys

Generate a new API key (MCP: generate_api_key).

Response: { success, data: { key, ... } }

curl -X POST 'https://api.roami.xyz/api/api-keys' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json' \
  -d '{"name":"Partner key"}'
DELETE/api/api-keys/:key

Revoke an API key (MCP: revoke_api_key).

Response: { success }

curl -X DELETE 'https://api.roami.xyz/api/api-keys/sk_...' \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json'