Summary and recommendation
Pardot API v5 is the only supported version; v3 and v4 are deprecated and end-of-life. Authentication is OAuth 2.0 via a Salesforce Connected App - legacy username/password auth from earlier API versions is not supported in v5. Every request must carry two headers: Authorization: Bearer <access_token> and Pardot-Business-Unit-Id: <id>.
Omitting the Business Unit ID header returns a 400 even with a valid token.
The user object exposes a salesforceId field (18-char Salesforce CRM User ID) and a crmUsername field, making it straightforward to build an identity graph that correlates Pardot user records with their upstream Salesforce identities.
This linkage is the reliable join key for any cross-system access audit or deprovisioning workflow - relying on email address alone is risky, as email mismatches between Salesforce and Pardot records are a documented source of sync errors.
Pagination is cursor-based via nextPageToken with a hard max of 200 records per page. The fields query parameter is required on most GET requests; omitting it returns a minimal default field set that may exclude role and status data.
API quick reference
| Has user API | Yes |
| Auth method | OAuth 2.0 (Salesforce Connected App; Bearer token in Authorization header) |
| Base URL | Official docs |
| SCIM available | No |
| SCIM plan required | N/A – Pardot itself has no native SCIM endpoint. SCIM provisioning is handled at the Salesforce platform level. |
Authentication
Auth method: OAuth 2.0 (Salesforce Connected App; Bearer token in Authorization header)
Setup steps
- Create a Connected App in Salesforce Setup with OAuth 2.0 enabled and the 'pardot_api' scope.
- Add 'pardot_api' and 'refresh_token' (or 'offline_access') OAuth scopes to the Connected App.
- Obtain an access token via Salesforce OAuth 2.0 token endpoint: POST https://login.salesforce.com/services/oauth2/token with grant_type=password or authorization_code flow.
- Include the Pardot Business Unit ID in every API request header: Pardot-Business-Unit-Id:
. - Pass the access token as: Authorization: Bearer
.
Required scopes
| Scope | Description | Required for |
|---|---|---|
| pardot_api | Grants access to Pardot API endpoints including user management. | All Pardot API calls |
| refresh_token / offline_access | Allows obtaining a refresh token for long-lived API access. | Non-interactive / server-to-server integrations |
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| id | integer | Pardot user ID | system-assigned | read-only | Pardot-internal ID, distinct from Salesforce User ID |
| salesforceId | string | Linked Salesforce CRM User ID (18-char) | required for SSO-enabled orgs | read-only after set | Required when Salesforce User Sync is enabled |
| string | User email address | required | optional | Must match Salesforce user email when synced | |
| firstName | string | User first name | required | optional | |
| lastName | string | User last name | required | optional | |
| jobTitle | string | User job title | optional | optional | |
| role | object | Pardot role assigned to the user (e.g., Administrator, Marketing, Sales) | required | optional | Role controls permissions within Pardot |
| isActive | boolean | Whether the user account is active | optional (default true) | optional | Setting false deactivates the user |
| createdAt | datetime | Timestamp of user creation (ISO 8601) | system-assigned | read-only | |
| updatedAt | datetime | Timestamp of last update (ISO 8601) | system-assigned | system-assigned | |
| timezone | string | User timezone (e.g., America/New_York) | optional | optional | |
| account | object | Pardot account/business unit association | system-assigned | read-only | |
| crmUsername | string | Salesforce CRM username of the linked user | read-only | read-only | Populated via Salesforce User Sync |
Core endpoints
List Users
- Method: GET
- URL:
https://pi.pardot.com/api/v5/objects/users - Watch out for: Returns max 200 records per page. Use nextPageToken for subsequent pages. Must specify desired fields via 'fields' query param.
Request example
GET /api/v5/objects/users?fields=id,email,firstName,lastName,isActive
Authorization: Bearer <token>
Pardot-Business-Unit-Id: <buId>
Response example
{
"values": [
{"id":1001,"email":"user@example.com","firstName":"Jane","lastName":"Doe","isActive":true}
],
"nextPageToken": "abc123"
}
Read User
- Method: GET
- URL:
https://pi.pardot.com/api/v5/objects/users/{id} - Watch out for: Requires specifying fields; omitting 'fields' param may return a minimal default set.
Request example
GET /api/v5/objects/users/1001?fields=id,email,firstName,lastName,role,isActive
Authorization: Bearer <token>
Pardot-Business-Unit-Id: <buId>
Response example
{
"id": 1001,
"email": "user@example.com",
"firstName": "Jane",
"lastName": "Doe",
"isActive": true,
"role": {"id": 3, "name": "Marketing"}
}
Create User
- Method: POST
- URL:
https://pi.pardot.com/api/v5/objects/users - Watch out for: When Salesforce User Sync is enabled (required for v5 SSO orgs), users must first exist in Salesforce CRM; direct Pardot user creation may be blocked or require a matching salesforceId.
Request example
POST /api/v5/objects/users
Content-Type: application/json
{
"email":"newuser@example.com",
"firstName":"John",
"lastName":"Smith",
"role":{"id":3}
}
Response example
{
"id": 1042,
"email": "newuser@example.com",
"firstName": "John",
"lastName": "Smith",
"isActive": true
}
Update User
- Method: PATCH
- URL:
https://pi.pardot.com/api/v5/objects/users/{id} - Watch out for: Deactivating a user (isActive: false) does not delete them. Email and salesforceId cannot be changed via API if Salesforce User Sync is active.
Request example
PATCH /api/v5/objects/users/1042
Content-Type: application/json
{
"firstName": "Jonathan",
"isActive": false
}
Response example
{
"id": 1042,
"firstName": "Jonathan",
"isActive": false
}
Delete User
- Method: DELETE
- URL:
https://pi.pardot.com/api/v5/objects/users/{id} - Watch out for: Deletion may be restricted when Salesforce User Sync is enabled; deactivation via isActive=false is the recommended approach instead.
Request example
DELETE /api/v5/objects/users/1042
Authorization: Bearer <token>
Pardot-Business-Unit-Id: <buId>
Response example
HTTP 204 No Content
Query Users by Email
- Method: GET
- URL:
https://pi.pardot.com/api/v5/objects/users?fields=id,email,isActive&email=user@example.com - Watch out for: Filter parameters are passed as query strings. Not all fields are filterable; consult v5 field reference for supported filter keys.
Request example
GET /api/v5/objects/users?fields=id,email,isActive&email=user%40example.com
Authorization: Bearer <token>
Pardot-Business-Unit-Id: <buId>
Response example
{
"values": [
{"id":1001,"email":"user@example.com","isActive":true}
]
}
List User Roles
- Method: GET
- URL:
https://pi.pardot.com/api/v5/objects/user-roles - Watch out for: Role IDs are needed when assigning roles during user create/update. Custom roles are supported in Advanced/Premium tiers.
Request example
GET /api/v5/objects/user-roles?fields=id,name
Authorization: Bearer <token>
Pardot-Business-Unit-Id: <buId>
Response example
{
"values": [
{"id":1,"name":"Administrator"},
{"id":3,"name":"Marketing"}
]
}
Rate limits, pagination, and events
- Rate limits: Pardot API enforces daily and concurrent request limits. As of API v5, the daily limit is tied to the Salesforce org API limit (shared with Salesforce API calls). Pardot-specific limit is 25,000 API calls per day for most editions.
- Rate-limit headers: No
- Retry-After header: No
- Rate-limit notes: Rate limit errors return HTTP 429. Pardot API v5 shares the Salesforce org's total API call budget. No standard rate-limit headers are documented for Pardot specifically.
- Pagination method: cursor
- Default page size: 200
- Max page size: 200
- Pagination pointer: nextPageToken
| Plan | Limit | Concurrent |
|---|---|---|
| Growth / Plus / Advanced | 25,000 API calls/day (shared Salesforce org limit) | 5 |
| Premium | Negotiated higher limits; subject to Salesforce org API allocation | 10 |
- Webhooks available: No
- Webhook notes: Pardot does not offer native outbound webhooks for user management events. Pardot does support 'Completion Actions' and 'Automation Rules' for prospect/lead events, but these do not cover user lifecycle events.
- Alternative event strategy: Use Salesforce Platform Events or Salesforce Flow to trigger external notifications when Pardot/Salesforce users are created, updated, or deactivated. Polling the Pardot Users API with updatedAt filtering is the standard approach for sync.
SCIM API status
- SCIM available: No
- SCIM version: Not documented
- Plan required: N/A – Pardot itself has no native SCIM endpoint. SCIM provisioning is handled at the Salesforce platform level.
- Endpoint: Not documented
Limitations:
- Pardot does not expose its own SCIM 2.0 endpoint.
- User provisioning via SCIM must be done through the Salesforce platform SCIM API (https://[instance].salesforce.com/services/scim/v2/Users), which syncs users into Salesforce CRM; Pardot users are then managed via Salesforce User Sync.
- Salesforce SCIM requires Salesforce Identity license or equivalent; available from Enterprise edition and above.
- SSO must be enabled on the Pardot account (Salesforce SSO is mandatory for API v5 user management).
Common scenarios
Three scenarios cover the majority of programmatic user lifecycle needs:
Provisioning: Create the user in Salesforce CRM first via the Salesforce REST API, wait for User Sync propagation (typically under 5 minutes), then optionally PATCH the Pardot user record to assign the correct Pardot role ID. Direct Pardot-only user creation is blocked or overwritten when User Sync is active.
Deprovisioning: Set IsActive=false on the Salesforce CRM user record first. If immediate Pardot-side deactivation is required before sync propagates, PATCH https://pi.pardot.com/api/v5/objects/users/{id} with {"isActive": false}. A Pardot-only deactivation without the corresponding Salesforce change will be reversed on the next sync cycle.
Access audit: GET /api/v5/objects/users with fields=id,email,firstName,lastName,role,isActive, paginate via nextPageToken until exhausted, then cross-reference role IDs against /api/v5/objects/user-roles. The isActive filter may not be supported as a server-side query param in all v5 releases - validate and fall back to client-side filtering if needed.
Provision a new Pardot user from an external HR system
- Create the user in Salesforce CRM via Salesforce REST API (POST /services/data/vXX.0/sobjects/User) with required profile and role.
- Wait for Pardot–Salesforce User Sync to propagate the user to Pardot (near real-time, typically < 5 minutes).
- Optionally verify the user exists in Pardot: GET https://pi.pardot.com/api/v5/objects/users?email=
&fields=id,isActive. - If Pardot role assignment is needed, PATCH https://pi.pardot.com/api/v5/objects/users/{id} with the desired role ID.
Watch out for: Attempting to create the user directly in Pardot API without first creating them in Salesforce CRM will fail or be overwritten when User Sync is enabled.
Deactivate a departed employee in Pardot
- Deactivate the user in Salesforce CRM (set IsActive=false via Salesforce API or UI); User Sync will propagate deactivation to Pardot automatically.
- To deactivate directly in Pardot without waiting for sync: PATCH https://pi.pardot.com/api/v5/objects/users/{pardotUserId} with body {"isActive": false}.
- Confirm deactivation: GET https://pi.pardot.com/api/v5/objects/users/{id}?fields=id,isActive.
Watch out for: If Salesforce User Sync is active, a Pardot-only deactivation may be re-activated on the next sync if the Salesforce user is still active. Always deactivate at the Salesforce level first.
Audit all active Pardot users and their roles
- GET https://pi.pardot.com/api/v5/objects/users?fields=id,email,firstName,lastName,role,isActive&isActive=true
- If response includes nextPageToken, repeat request with query param nextPageToken=
until no token is returned. - Collect all user records and cross-reference role IDs against GET https://pi.pardot.com/api/v5/objects/user-roles?fields=id,name.
- Export compiled list for access review.
Watch out for: Max page size is 200 records. Large orgs must paginate fully. The isActive filter may not be supported as a query param in all API versions; validate against v5 field reference and fall back to client-side filtering if needed.
Why building this yourself is a trap
The most consequential API caveat is the shared API call budget: Pardot API v5 draws from the same daily Salesforce org allocation (25,000 calls/day on most editions).
Heavy Pardot API usage can exhaust limits for other Salesforce integrations running in the same org - this is not surfaced in Pardot-specific rate-limit headers, which are not documented for v5.
Access tokens expire after a configurable session timeout (Salesforce default is 2 hours). Long-running integrations must implement refresh token rotation using the refresh_token or offline_access OAuth scope; failing to do so produces silent auth failures in background jobs.
For teams building on an MCP server with 60+ deep IT/identity integrations, the Pardot identity graph - anchored on the salesforceId and crmUsername fields - is the correct join key for cross-system deprovisioning.
Email-based identity resolution will silently break when Salesforce and Pardot email records diverge, which is a documented failure mode in orgs that have undergone email address changes or domain migrations.
Automate Pardot workflows without one-off scripts
Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.