Skip to main content

Ambient REST API Developer Guide

Written by Taylor McLoughlin
Updated today

Overview

The Ambient REST API gives you programmatic access to your organization's meeting summaries, transcripts, email summaries, Slack digests, projects, files, and AI-generated insights. It is a read-only, RESTful JSON API designed for AI workflows and integrations.

If you are looking for MCP (Model Context Protocol) integration instead, see our MCP documentation. This guide covers the standalone REST API only.


Authentication

All requests require an API key passed as a Bearer token in the Authorization header.

curl

curl -H "Authorization: Bearer YOUR_API_KEY" \   https://api.ambient.us/v1/whoami

Python

import requests  API_KEY = "YOUR_API_KEY" BASE_URL = "https://api.ambient.us/v1" HEADERS = {"Authorization": f"Bearer {API_KEY}"}  response = requests.get(f"{BASE_URL}/whoami", headers=HEADERS) print(response.json())

JavaScript

const API_KEY = "YOUR_API_KEY"; const BASE_URL = "https://api.ambient.us/v1";  const response = await fetch(`${BASE_URL}/whoami`, {   headers: { Authorization: `Bearer ${API_KEY}` }, }); const data = await response.json(); console.log(data);

The /whoami endpoint returns your key type, user details, organization ID, and granted scopes. Use it to verify your key is working.

Key types

Key type

Description

user

Scoped to a specific user within an organization

user_org

A user key with organization-wide access

org

Organization-wide access without a specific user

To get an API key, visit Workspace Settings in the Ambient app.


Core concepts

Resource types

Ambient organizes data into a few core resource types:

Resource

Description

ID prefix

Artifacts

Meeting summaries, email summaries, and Slack digests

art_

Meetings

Calendar meetings with attendee info

mtg_

Insights

AI-generated content like meeting dossiers and daily briefings

ins_

Projects

Organizational groupings for artifacts and files

prj_

Files

Uploaded documents associated with projects

fil_

All IDs use a type-prefixed format (e.g., art_550e8400-e29b-41d4-a716-446655440000). The prefix and ID value are stable and will not change for a given resource.

Expansions (the include parameter)

To keep responses lightweight, most content fields are omitted by default. Use the include query parameter to expand the fields you need. Pass multiple expansions as a comma-separated list.

For example, to get artifact text content and attendees:

GET /v1/artifacts?include=text_content,attendees

Each resource type supports different expansions, documented in the endpoint sections below.

Pagination

All list endpoints use cursor-based pagination.

Parameter

Description

limit

Number of results per page (1-200, default 50)

cursor

Opaque cursor returned as next_cursor in the previous response

When next_cursor is null, there are no more results.

Python example: paginating through all artifacts

cursor = None  while True:     params = {"limit": 100, "include": "text_content"}     if cursor:         params["cursor"] = cursor      response = requests.get(f"{BASE_URL}/artifacts", headers=HEADERS, params=params)     data = response.json()      for artifact in data["data"]:         print(artifact["title"])      cursor = data.get("next_cursor")     if not cursor:         break

Endpoints

Artifacts

Artifacts are the primary content objects in Ambient. They come in three types:

Type

Description

meeting_summary

Generated from a recorded meeting

email_summary

Generated from connected email

slack_digest

Generated from connected Slack channels

List artifacts

GET /v1/artifacts

Query parameters:

Parameter

Type

Description

type

string

Filter by artifact type: meeting_summary, email_summary, slack_digest

project_id

string

Filter to artifacts in a specific project

meeting_id

string

Filter to artifacts from a specific meeting

q

string

Search artifact titles (case-insensitive substring match)

attendee_email

string

Filter to artifacts from meetings with this attendee

attendee_domain

string

Filter by attendee email domain (e.g., acme.com)

status

string

published (default), draft, or any

created_after

datetime

Only return artifacts created after this timestamp

updated_after

datetime

Only return artifacts updated after this timestamp

order

string

created_at:asc, created_at:desc, effective_date:asc, effective_date:desc

include

string

Comma-separated: text_content, json_content, meeting, transcript, action_items, project_ids, attendees

limit

integer

Results per page (1-200, default 50)

cursor

string

Pagination cursor

Get a single artifact

GET /v1/artifacts/{artifact_id}

Supports the same include parameter as the list endpoint.


Meetings

Meetings represent calendar events from connected calendars.

List meetings

GET /v1/meetings

Query parameters:

Parameter

Type

Description

ical_uid

string

Filter by iCal UID

q

string

Search meeting titles (case-insensitive substring match)

attendee_email

string

Filter to meetings with this attendee

attendee_domain

string

Filter by attendee email domain

starts_at_gte

datetime

Meetings starting at or after this time

starts_at_lte

datetime

Meetings starting at or before this time

include_shared

boolean

Include meetings where you have access to a linked artifact (default: false)

order

string

starts_at:asc, starts_at:desc

include

string

Comma-separated: attendees, artifacts, insights

limit

integer

Results per page (1-200, default 50)

cursor

string

Pagination cursor

Get a single meeting

GET /v1/meetings/{meeting_id}

Insights

Insights are AI-generated content like pre-meeting dossiers and daily briefings.

Type

Description

meeting_dossier

Pre-meeting research: attendee context, related meetings, conversation starters

daily_briefing

Once-a-day summary of upcoming meetings

List insights

GET /v1/insights

Query parameters:

Parameter

Type

Description

type

string

Filter by type: meeting_dossier, daily_briefing

resource_id

string

Filter by related resource (e.g., a meeting ID for dossiers)

created_after

datetime

Only return insights created after this timestamp

order

string

created_at:asc, created_at:desc

include

string

Comma-separated: text_content, json_content, meeting

limit

integer

Results per page (1-200, default 50)

cursor

string

Pagination cursor

Get a single insight

GET /v1/insights/{insight_id}

Projects

Projects are organizational groupings for artifacts and files.

List projects

GET /v1/projects

Returns active projects only (archived projects are excluded).

Get a single project

GET /v1/projects/{project_id}

List artifacts in a project

GET /v1/projects/{project_id}/artifacts

Supports the same query parameters and include options as the main artifacts list endpoint.

List files in a project

GET /v1/projects/{project_id}/files

Files

Files are documents uploaded to projects.

List files

GET /v1/files

Query parameters:

Parameter

Type

Description

project_id

string

Filter to files in a specific project

updated_after

datetime

Only return files updated after this timestamp

order

string

updated_at:asc, updated_at:desc, created_at:asc, created_at:desc

include

string

Comma-separated: text_content, generated_summary, project_ids

limit

integer

Results per page (1-200, default 50)

cursor

string

Pagination cursor

Note: When using include=text_content on list endpoints, the server may return a 400 error if the combined content is too large. Use the single-file endpoint for large text content.

Get a single file

GET /v1/files/{file_id}

Common workflows

Pull transcripts with participant info

This is the most common integration pattern. A single API call retrieves meeting transcripts alongside attendee details.

curl

curl -H "Authorization: Bearer YOUR_API_KEY" \   "https://api.ambient.us/v1/artifacts?type=meeting_summary&include=transcript,attendees&order=effective_date:desc&limit=10"

Python

response = requests.get(     f"{BASE_URL}/artifacts",     headers=HEADERS,     params={         "type": "meeting_summary",         "include": "transcript,attendees",         "order": "effective_date:desc",         "limit": 10,     }, )  for artifact in response.json()["data"]:     print(f"\n--- {artifact['title']} ---")      # Attendees     if artifact.get("attendees"):         for attendee in artifact["attendees"]:             role = " (organizer)" if attendee["is_organizer"] else ""             print(f"  {attendee.get('display_name', 'Unknown')} <{attendee.get('email', 'N/A')}>{role}")      # Transcript     transcript = artifact.get("transcript", {})     if transcript and transcript.get("disposition") == "AVAILABLE":         print(f"\nTranscript:\n{transcript['text_content'][:500]}...")

JavaScript

const response = await fetch(   `${BASE_URL}/artifacts?type=meeting_summary&include=transcript,attendees&order=effective_date:desc&limit=10`,   { headers: { Authorization: `Bearer ${API_KEY}` } } ); const { data: artifacts } = await response.json();  for (const artifact of artifacts) {   console.log(`\n--- ${artifact.title} ---`);    // Attendees   artifact.attendees?.forEach((a) => {     const role = a.is_organizer ? " (organizer)" : "";     console.log(`  ${a.display_name ?? "Unknown"} <${a.email ?? "N/A"}>${role}`);   });    // Transcript   if (artifact.transcript?.disposition === "AVAILABLE") {     console.log(`\nTranscript:\n${artifact.transcript.text_content.slice(0, 500)}...`);   } }

The transcript is returned as plain text with speaker labels and timecodes. Each line follows the format [m:ss] Speaker: text (or [h:mm:ss] for longer recordings).

Find meetings with a specific person or company

Filter artifacts by attendee email or email domain:

# All meetings with a specific person curl -H "Authorization: Bearer YOUR_API_KEY" \   "https://api.ambient.us/v1/artifacts?attendee_email=jane@acme.com&include=text_content,attendees"  # All meetings with anyone from a company curl -H "Authorization: Bearer YOUR_API_KEY" \   "https://api.ambient.us/v1/artifacts?attendee_domain=acme.com&include=text_content,attendees"

Get meeting summaries with action items

curl -H "Authorization: Bearer YOUR_API_KEY" \   "https://api.ambient.us/v1/artifacts?type=meeting_summary&include=text_content,action_items&order=effective_date:desc&limit=5"

Action items include a description, status (OPEN, DONE, INPROGRESS), importance level, optional due date, and an owner with name and email when available.

Get pre-meeting dossiers

Retrieve AI-generated research for upcoming meetings:

# Get dossier for a specific meeting curl -H "Authorization: Bearer YOUR_API_KEY" \   "https://api.ambient.us/v1/insights?type=meeting_dossier&resource_id=mtg_YOUR_MEETING_ID&include=text_content"  # Get recent dossiers curl -H "Authorization: Bearer YOUR_API_KEY" \   "https://api.ambient.us/v1/insights?type=meeting_dossier&include=text_content&order=created_at:desc&limit=5"

Sync new artifacts since last pull

Use created_after or updated_after to implement incremental sync:

from datetime import datetime, timezone  # Store this timestamp between sync runs last_sync = "2026-03-01T00:00:00Z"  response = requests.get(     f"{BASE_URL}/artifacts",     headers=HEADERS,     params={         "updated_after": last_sync,         "include": "text_content,attendees",         "order": "created_at:asc",         "limit": 200,     }, )  artifacts = response.json()["data"] print(f"Found {len(artifacts)} new/updated artifacts since {last_sync}")  # Update last_sync to now for next run last_sync = datetime.now(timezone.utc).isoformat()

Error handling

The API returns standard HTTP status codes with structured error responses:

{   "error": {     "code": "not_found",     "message": "Artifact not found",     "request_id": "req_01HZZ..."   } }

Status

Meaning

200

Success

400

Bad request (invalid parameters, response too large)

401

Unauthorized (invalid or missing API key)

404

Resource not found or not accessible

Include the request_id from error responses when contacting support.


Rate limits and best practices

  • Use include selectively. Only request the expansions you need to keep responses fast and small.

  • Paginate with reasonable page sizes. The default of 50 works well for most use cases. The maximum is 200.

  • Use created_after / updated_after for incremental sync rather than re-fetching everything.

  • When using include=text_content on list endpoints, be aware the server may reject requests where the combined content is too large. Use the single-resource endpoint as a fallback.

  • Cache the next_cursor value if your process might be interrupted mid-pagination.


Need help?

If you have questions or run into issues, reach out to us at support@ambient.us or through the in-app chat.

Did this answer your question?