A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.
The Marketo API is how an app or AI agent works with a Marketo Engage instance: reading and syncing leads, adding or removing them from a static list, reading the activities a lead has taken, and triggering a campaign to run against a set of people. Access is granted through an OAuth access token tied to an API user, and what that token can do is decided by the broad permissions on the user's role rather than per-call scopes. Marketo does not push events to a listener, so an integration learns about changes by reading the activity endpoints from a paging token.
How an app or AI agent connects to Marketo determines what it can reach. There is the REST API for making calls and a hosted server that exposes Marketo operations to agents, and each is governed by the API user behind it and the permissions on that user's role.
The REST API answers at a per-instance host, https://{munchkinId}.mktorest.com, found under Admin in the Marketo instance. The Lead Database calls live under /rest/v1, the Asset calls under /rest/asset/v1, and bulk import and extract under /bulk/v1. A call carries an OAuth 2.0 access token in an Authorization Bearer header.
Adobe hosts a Marketo Engage Model Context Protocol server at https://marketo-mcp.adobe.io/mcp, in limited availability, which exposes more than 100 operations across forms, programs, smart campaigns, leads, emails, snippets, lists, and folders. An AI tool passes Marketo client credentials, the Client ID, Client Secret, and Munchkin account id, as HTTP headers on each request, and the server runs the matching REST API call. The server does not store or cache those credentials.
Marketo authenticates with the OAuth 2.0 client credentials flow. A custom service is created in Admin with an associated API-only user, which yields a Client ID and Client Secret. A call to the identity endpoint at /identity/oauth/token with grant_type=client_credentials returns an access token that lasts 3600 seconds, sent on each request as an Authorization Bearer header. Passing the token as an access_token query parameter is deprecated and stops working after 31 July 2026.
The Marketo API is split into a Lead Database side, covering leads, their activities, static lists, and custom objects, and an Asset side, covering programs, emails, and smart campaigns. Each area maps to a permission on the API user's role, and a write in some areas changes live marketing records or runs a campaign against real people.
Get a lead by id, query leads by filter, create, update, and delete leads, merge duplicates, and describe the available lead fields.
List static lists, read a list, list its members, and add or remove leads from a static list.
Get a paging token, read lead activities, list activity types, read lead field changes and deleted leads, and add custom activities.
List custom object types, describe one's fields, sync (insert, update, upsert) records, and delete records.
List campaigns, read a campaign, trigger a campaign against a set of leads, schedule a campaign, and list or read smart campaigns.
Browse programs and read a single program by id.
Browse email assets and read a single email by id.
Submit a bulk lead import job from a file and poll its status, failures, and warnings.
Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.
| Method | Endpoint | What it does | Access | Permission | Version | |
|---|---|---|---|---|---|---|
LeadsGet a lead by id, query leads by filter, create, update, and delete leads, merge duplicates, and describe the available lead fields.6 | ||||||
| GET | /rest/v1/lead/{id}.json | Get a single lead by its id, with default or specified fields. | read | Read-Only Lead | Current | |
Granted by the Read-Only Lead permission on the API user's role. Acts onlead Permission (capability) Read-Only LeadVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /rest/v1/leads.json | Query multiple leads by a filter type and values, returning up to 300 per page. | read | Read-Only Lead | Current | |
filterType and filterValues are required; results page with nextPageToken. Acts onlead Permission (capability) Read-Only LeadVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /rest/v1/leads.json | Create or update lead records (createOnly, updateOnly, createOrUpdate, createDuplicate), up to 300 per request. | write | Read-Write Lead | Current | |
The same endpoint handles create and update, chosen by the action field. Granted by Read-Write Lead. Acts onlead Permission (capability) Read-Write LeadVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /rest/v1/leads/delete.json | Delete lead records by id, up to 300 per request. | write | Read-Write Lead | Current | |
Deletes are irreversible. Uses POST, not the DELETE method. Acts onlead Permission (capability) Read-Write LeadVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /rest/v1/leads/{id}/merge.json | Merge duplicate leads into one, with the winning lead in the path and the losing leads in parameters. | write | Read-Write Lead | Current | |
The merge cannot be undone; the losing records are removed. Acts onlead Permission (capability) Read-Write LeadVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /rest/v1/leads/describe.json | List the lead fields available through the REST API, with their data types and names. | read | Read-Only Lead | Current | |
Used to discover field names before reading or writing leads. Acts onlead field Permission (capability) Read-Only LeadVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Lead listsList static lists, read a list, list its members, and add or remove leads from a static list.6 | ||||||
| GET | /rest/v1/lists.json | List static lists in the instance. | read | Read-Only Lead | Current | |
Static list membership is governed by the Lead permissions. Acts onstatic list Permission (capability) Read-Only LeadVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /rest/v1/lists/{id}.json | Get a single static list by its id. | read | Read-Only Lead | Current | |
Read-only. Acts onstatic list Permission (capability) Read-Only LeadVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /rest/v1/lists/{listId}/leads.json | Get the leads that are members of a static list. | read | Read-Only Lead | Current | |
Returns list members; pages with nextPageToken. Acts onstatic list Permission (capability) Read-Only LeadVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /rest/v1/lists/{listId}/leads.json | Add leads to a static list, up to 300 ids per request. | write | Read-Write Lead | Current | |
Adding to a list can make those leads targets of campaigns that watch the list. Acts onstatic list Permission (capability) Read-Write LeadVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /rest/v1/lists/{listId}/leads.json | Remove leads from a static list, up to 300 ids per request. | write | Read-Write Lead | Current | |
Removes the leads from the list without deleting the lead records. Acts onstatic list Permission (capability) Read-Write LeadVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /rest/v1/lists/{listId}/leads/ismember.json | Check whether given leads are members of a static list. | read | Read-Only Lead | Current | |
Read-only membership check by lead id. Acts onstatic list Permission (capability) Read-Only LeadVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
ActivitiesGet a paging token, read lead activities, list activity types, read lead field changes and deleted leads, and add custom activities.6 | ||||||
| GET | /rest/v1/activities/pagingtoken.json | Get a paging token for a start datetime, used as the cursor for reading activities and changes since that point. | read | Read-Only Activity | Current | |
sinceDatetime must be ISO 8601 and URL encoded; the returned token feeds the activity reads. Acts onpaging token Permission (capability) Read-Only ActivityVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /rest/v1/activities.json | Get lead activities of specified types since a paging token, optionally filtered by lead or list. | read | Read-Only Activity | Current | |
Requires a nextPageToken and activityTypeIds. This is how an integration learns about changes without a push. Acts onactivity Permission (capability) Read-Only ActivityVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /rest/v1/activities/types.json | List the available activity types and their definitions for the instance. | read | Read-Only Activity | Current | |
Used to find the activityTypeIds passed to the activities read. Acts onactivity type Permission (capability) Read-Only ActivityVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /rest/v1/activities/leadchanges.json | Get data value change records for specified lead fields since a paging token. | read | Read-Only Activity | Current | |
Requires a fields parameter and a nextPageToken. Acts ondata value change Permission (capability) Read-Only ActivityVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /rest/v1/activities/deletedleads.json | Get records of leads deleted since a paging token. | read | Read-Only Activity | Current | |
Used to keep an external copy in sync with deletions. Acts ondeleted lead Permission (capability) Read-Only ActivityVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /rest/v1/activities/external.json | Add custom activity records against leads, up to 300 per request. | write | Read-Write Activity | Current | |
The activity type must be defined first; granted by Read-Write Activity. Acts oncustom activity Permission (capability) Read-Write ActivityVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Custom objectsList custom object types, describe one's fields, sync (insert, update, upsert) records, and delete records.4 | ||||||
| GET | /rest/v1/customobjects.json | List the custom object types defined in the instance. | read | Read-Only Custom Object | Current | |
Read-only; lists object names to use in the other custom object calls. Acts oncustom object Permission (capability) Read-Only Custom ObjectVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /rest/v1/customobjects/{customObjectName}/describe.json | Describe a custom object's fields, dedupe fields, relationships, and searchable fields. | read | Read-Only Custom Object | Current | |
Read the structure before syncing records. Acts oncustom object Permission (capability) Read-Only Custom ObjectVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /rest/v1/customobjects/{customObjectName}.json | Insert, update, or upsert records of a custom object. | write | Read-Write Custom Object | Current | |
The action field chooses createOnly, updateOnly, or createOrUpdate. Granted by Read-Write Custom Object. Acts oncustom object Permission (capability) Read-Write Custom ObjectVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /rest/v1/customobjects/{customObjectName}/delete.json | Delete records of a custom object by their dedupe or id fields. | write | Read-Write Custom Object | Current | |
Deletes are irreversible; uses POST, not the DELETE method. Acts oncustom object Permission (capability) Read-Write Custom ObjectVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
CampaignsList campaigns, read a campaign, trigger a campaign against a set of leads, schedule a campaign, and list or read smart campaigns.6 | ||||||
| GET | /rest/v1/campaigns.json | List campaigns, including trigger and batch campaigns, filterable by id, name, or program. | read | Read-Only Campaign | Current | |
Read-only; finds the campaign id used to trigger or schedule. Acts oncampaign Permission (capability) Read-Only CampaignVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /rest/v1/campaigns/{id}.json | Get a single campaign by its id. | read | Read-Only Campaign | Current | |
Read-only. Acts oncampaign Permission (capability) Read-Only CampaignVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /rest/v1/campaigns/{id}/trigger.json | Request a trigger campaign to run its flow against a set of leads passed in the call. | write | Execute Campaign | Current | |
The campaign must have a Campaign is Requested trigger with source Web Service API. Granted by the Execute Campaign permission. Acts oncampaign Permission (capability) Execute CampaignVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /rest/v1/campaigns/{id}/schedule.json | Schedule a batch campaign to run at a given time, with optional token overrides. | write | Execute Campaign | Current | |
Runs a batch campaign against its own smart list, not a passed-in set of leads. Acts oncampaign Permission (capability) Execute CampaignVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /rest/asset/v1/smartCampaigns.json | Browse smart campaigns as assets, filterable by date and folder. | read | Read-Only Asset | Current | |
The Asset API governs smart campaigns by the Asset permissions, not the Campaign permission. Acts onsmart campaign Permission (capability) Read-Only AssetVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /rest/asset/v1/smartCampaign/{id}/activate.json | Activate a smart campaign so its triggers begin to run. | write | Read-Write Asset | Current | |
The campaign must have at least one trigger and flow step and be error free. Acts onsmart campaign Permission (capability) Read-Write AssetVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
ProgramsBrowse programs and read a single program by id.2 | ||||||
| GET | /rest/asset/v1/programs.json | Browse programs, with optional filtering by status, date range, and folder. | read | Read-Only Asset | Current | |
Read-only; the Asset side of the API is governed by the Asset permissions. Acts onprogram Permission (capability) Read-Only AssetVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /rest/asset/v1/program/{id}.json | Get a single program by its id, with optional tags and costs. | read | Read-Only Asset | Current | |
Read-only. Acts onprogram Permission (capability) Read-Only AssetVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
EmailsBrowse email assets and read a single email by id.2 | ||||||
| GET | /rest/asset/v1/emails.json | Browse email assets, with optional filtering by status and folder. | read | Read-Only Asset | Current | |
Read-only. Acts onemail Permission (capability) Read-Only AssetVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /rest/asset/v1/email/{id}.json | Get a single email asset by its id. | read | Read-Only Asset | Current | |
Read-only. Acts onemail Permission (capability) Read-Only AssetVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Bulk importSubmit a bulk lead import job from a file and poll its status, failures, and warnings.4 | ||||||
| POST | /bulk/v1/leads.json | Submit a bulk import job for lead records from a CSV, TSV, or SSV file up to 10MB. | write | Read-Write Lead | Current | |
Returns a batchId; the job runs asynchronously and is polled for status. Acts onimport batch Permission (capability) Read-Write LeadVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /bulk/v1/leads/batch/{id}.json | Get the status of a bulk lead import job, such as Queued, Importing, Complete, or Failed. | read | Read-Only Lead | Current | |
Polled until the job leaves Queued or Importing. Acts onimport batch Permission (capability) Read-Only LeadVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /bulk/v1/leads/batch/{id}/failures.json | Get the rows that failed during a bulk lead import, with a failure reason on each. | read | Read-Only Lead | Current | |
Available after the job completes. Acts onimport batch Permission (capability) Read-Only LeadVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /bulk/v1/leads/batch/{id}/warnings.json | Get the rows that produced a warning during a bulk lead import, with a warning on each. | read | Read-Only Lead | Current | |
Available after the job completes. Acts onimport batch Permission (capability) Read-Only LeadVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Marketo does not push REST API events to a listener. What Marketo calls a webhook is an outbound HTTP call configured as a flow step inside a smart campaign, which posts lead data to an external URL when a lead flows through that step. An integration that wants to learn about changes polls the activity endpoints with a paging token instead.
| Event | What it signals | Triggered by |
|---|
Marketo limits how fast and how much an app or AI agent can call, through a short-window rate measured per twenty seconds, a daily call quota per instance, and a separate cap on how many calls run at once.
Marketo meters by the instance, not per method. Calls are capped at 100 in any rolling 20-second window, returning error 606 when exceeded, and at most ten calls may run at once, returning error 615 over that. A separate daily quota, 50,000 calls by default, resets at midnight US Central time and returns error 607 when reached. Bulk import and extract help stay under the per-call limits by moving large jobs into a single asynchronous job rather than many small calls.
Most read endpoints page with a token. A query returns up to 300 records with a nextPageToken, which is passed back on the next call until no token is returned. Time-based reads of activities, lead changes, and deleted leads start from a paging token obtained by calling Get Paging Token with a start datetime.
Lead reads and writes are capped at 300 records per call, and add or remove from list at 300 ids per call. A bulk lead import file may be up to 10MB and must be CSV, TSV, or SSV.
The status codes an agent should handle, and what to do about each.
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 200 | success:false (601 Access token invalid) | Marketo returns HTTP 200 even on failure, with success:false and an errors array of code and message. Code 601 means the access token is invalid. | Request a fresh access token from the identity endpoint and retry. |
| 200 | 602 Access token expired | The access token has passed its one-hour lifetime. | Fetch a new token and retry; cache tokens and refresh before expiry. |
| 200 | 603 Access denied | The API user's role lacks the permission the call needs, such as Read-Write Lead for a write. | Grant the matching permission on the API user's role in Admin. |
| 200 | 606 Max rate limit exceeded | More than 100 calls were made within a 20-second window for the instance. | Back off and retry after the window, and smooth the request rate. |
| 200 | 607 Daily quota reached | The instance has used its daily call allowance, which resets at midnight US Central time. | Wait for the daily reset or request a higher quota, and batch calls where possible. |
| 200 | 615 Concurrent access limit reached | More than ten calls ran at the same time for the instance. | Cap concurrency at ten and queue further calls. |
| 200 | 610 Requested resource not found | The id or object in the path does not exist or is not visible to this instance. | Verify the id and the object name before retrying. |
Marketo's REST API is on a single version, v1 for the Lead Database and v1 for Asset, and ships dated changes through the Marketo Engage release notes rather than minting new version numbers.
The Marketo REST API stays on path version v1 for Lead Database and Asset calls and v1 for bulk, and does not mint new version numbers for changes. Instead it ships dated changes, deprecations, and end-of-life notices through the Marketo Engage release notes. The entries below are notable dated changes from those notes.
Two long-standing capabilities are removed on 31 July 2026. The access_token query parameter for authenticating REST calls stops working, so all calls must send the token in an Authorization header. Support for the Marketo SOAP API ends the same day, and SOAP-based integrations must move to REST.
Adobe introduced the Marketo Engage MCP server, a hosted Model Context Protocol bridge that exposes more than 100 operations across forms, programs, smart campaigns, people, emails, snippets, lists, and folders to AI tools, running the matching REST API call per request.
Adobe moved REST API URLs to a more modern hosting infrastructure for added security and scalability. Subscriptions whose API URLs contained a double forward slash needed to follow a documented update.
From 30 September 2026, Get Lead Activities and Get Lead Changes calls that include a listId pointing at a static list of 10,000 or more leads return a 1003 error, pushing large reads toward other filters or bulk extract.
The path version stays v1; track the release notes for dated changes and deprecations.
Marketo Engage release notes ↗Bollard AI sits between a team's AI agents and Marketo. Grant each agent exactly the access it needs, read or write, area by area, and every call is checked and logged.