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.
Base URL: https://api.ambient.us/v1
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 |
| Scoped to a specific user within an organization |
| A user key with organization-wide access |
| 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 |
|
Meetings | Calendar meetings with attendee info |
|
Insights | AI-generated content like meeting dossiers and daily briefings |
|
Projects | Organizational groupings for artifacts and files |
|
Files | Uploaded documents associated with projects |
|
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 |
| Number of results per page (1-200, default 50) |
| Opaque cursor returned as |
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: breakEndpoints
Artifacts
Artifacts are the primary content objects in Ambient. They come in three types:
Type | Description |
| Generated from a recorded meeting |
| Generated from connected email |
| Generated from connected Slack channels |
List artifacts
GET /v1/artifacts
Query parameters:
Parameter | Type | Description |
| string | Filter by artifact type: |
| string | Filter to artifacts in a specific project |
| string | Filter to artifacts from a specific meeting |
| string | Search artifact titles (case-insensitive substring match) |
| string | Filter to artifacts from meetings with this attendee |
| string | Filter by attendee email domain (e.g., |
| string |
|
| datetime | Only return artifacts created after this timestamp |
| datetime | Only return artifacts updated after this timestamp |
| string |
|
| string | Comma-separated: |
| integer | Results per page (1-200, default 50) |
| 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 |
| string | Filter by iCal UID |
| string | Search meeting titles (case-insensitive substring match) |
| string | Filter to meetings with this attendee |
| string | Filter by attendee email domain |
| datetime | Meetings starting at or after this time |
| datetime | Meetings starting at or before this time |
| boolean | Include meetings where you have access to a linked artifact (default: false) |
| string |
|
| string | Comma-separated: |
| integer | Results per page (1-200, default 50) |
| 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 |
| Pre-meeting research: attendee context, related meetings, conversation starters |
| Once-a-day summary of upcoming meetings |
List insights
GET /v1/insights
Query parameters:
Parameter | Type | Description |
| string | Filter by type: |
| string | Filter by related resource (e.g., a meeting ID for dossiers) |
| datetime | Only return insights created after this timestamp |
| string |
|
| string | Comma-separated: |
| integer | Results per page (1-200, default 50) |
| 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}/artifactsSupports the same query parameters and include options as the main artifacts list endpoint.
List files in a project
GET /v1/projects/{project_id}/filesFiles
Files are documents uploaded to projects.
List files
GET /v1/files
Query parameters:
Parameter | Type | Description |
| string | Filter to files in a specific project |
| datetime | Only return files updated after this timestamp |
| string |
|
| string | Comma-separated: |
| integer | Results per page (1-200, default 50) |
| 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
includeselectively. 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_afterfor incremental sync rather than re-fetching everything.When using
include=text_contenton 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_cursorvalue 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.
