A user is a person who signs in to your SparkPost account. Every user is scoped either to the primary account, where a single role sets what they can do, or to one or more subaccounts, where they hold a role on each. Use this API to list users, invite new ones, change their roles, and remove them.
The access_level field sets a user's role when you invite or update them. The primary-account roles are:
| Role | Description |
|---|---|
admin | Full access to the account, including user and billing management. |
developer | Access to sending and configuration APIs, without account administration. |
reporting | Read-only access to reporting and analytics. |
templates | Access limited to managing templates. |
custom | A role whose permissions are defined by the access_policies you supply. |
Subaccount-scoped users take subaccount_reporting or subaccount_developer instead.
A user with the custom role gets exactly the policies you list in access_policies. The field is valid only when access_level is custom.
| Policy | Grants |
|---|---|
alerts/full | View and manage alerts. |
api_keys/full | Manage API keys. |
ab_testing/full | View and manage A/B tests of email templates. |
domains/full | View and manage sending, bounce, and tracking domains. |
events/read | View and search message events. |
ip_pools/full | View and manage IP pools. |
recipient_lists/full | View and manage recipient lists. |
recipient_validation/full | Validate email addresses and view recent validations. |
seeds/full | View seeding activity and manage seed list settings. |
signals_analytics/full | View and manage analytics metrics, dashboards, and reports, including health score, spam traps, engagement recency, and blocklist incidents. |
subaccounts/full | Manage subaccounts. |
suppressions/full | View and manage suppressions. |
templates/full | View, manage, and preview email templates and snippets. |
users/full | View and manage users. |
webhooks/full | View, manage, and test webhooks. |
Returned by List Users and Retrieve a User.
A primary-account user has an access_level. A subaccount-scoped user has none, and holds a role on each subaccount instead.
{
"username": "grace",
"first_name": "Grace",
"last_name": "Hopper",
"email": "grace@example.com",
"access_level": "reporting",
"is_sso": false,
"email_verified": true,
"tfa_enabled": true,
"last_login": "2026-08-02T09:14:05.000Z",
"created": "2015-01-11T08:00:00.000Z",
"updated": "2018-04-11T08:00:00.000Z",
"subaccounts": []
}
Unique username that identifies the user.
The user's first name. Only present when the user has set it.
The user's last name. Only present when the user has set it.
The user's email address.
The user's role on the primary account. Absent for subaccount-scoped users.
Possible Values: admin, developer, reporting, templates, custom
The access policies granted to the user. Only present when access_level is custom.
Whether the user signs in through single sign-on.
Whether the user has verified their email address. Always true for a single sign-on user, because the identity provider confirms the address.
Whether the user has two-factor authentication enabled.
ISO 8601 timestamp of the user's last sign-in, or null if they have never signed in.
The subaccounts the user has access to, and the user's role on each. See Subaccount access object. Returned only by Retrieve a User, and empty for a primary-account user.
ISO 8601 timestamp of when the user was created. Returned only by Retrieve a User.
ISO 8601 timestamp of when the user was last updated. Returned only by Retrieve a User.
Each object in a user's subaccounts array describes one subaccount the user has access to, and the user's role on it.
{
"subaccount_id": 123,
"subaccount_name": "Joe's Garage",
"access_level": "subaccount_reporting",
"status": "active"
}
The subaccount ID.
The subaccount's display name.
The user's role on the subaccount.
Possible Values: subaccount_reporting, subaccount_developer
The subaccount's status. Returned only by Retrieve a User.
Possible Values: active, suspended, terminated
Returned by List Pending Invites.
{
"id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
"email": "newuser@example.com",
"from": "ada@example.com",
"access_level": "reporting",
"expires": "2024-07-11T00:00:00.000Z"
}
Unique ID of the pending invite.
The email address the invite was sent to.
The email address of the user who created the invite.
The role the user gets when they register.
Possible Values: admin, developer, reporting, templates, custom
The access policies the user gets when they register, if access_level is custom.
The subaccount access the user gets when they register. See Subaccount invite object. Present instead of access_level for a subaccount-scoped invite.
ISO 8601 timestamp of when the invite expires.
Each object in the subaccounts array of an Invite a User request grants the invitee access to one subaccount, with the role you set.
{
"subaccount_id": 123,
"access_level": "subaccount_reporting"
}
The subaccount ID.
The role to grant on the subaccount.
Possible Values: subaccount_reporting, subaccount_developer
An invite expires three days after you create it. The registration link then stops working, and the invite drops off List Pending Invites.
To give someone another chance to register, invite the same email address again. That creates a second, independent invite with its own expiry. The first one keeps working until it expires or you revoke it.
POST /api/v1/users/invite{
"email": "newuser@example.com",
"access_level": "reporting"
}
{
"results": {
"id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301"
}
}
Creates an invite and emails a registration link to the address you supply. The invitee follows the link, sets their own password, and gets the role you set in access_level. The response carries the invite id, which you use to list and revoke the invite.
Send access_level to invite a primary-account user, or subaccounts to invite a subaccount-scoped one.
On an account with SAML single sign-on enabled, there is no password to set, so this endpoint skips the invite and creates the user immediately with is_sso true. The email tells the user to sign in through your identity provider. The single sign-on path differs in three ways:
The response carries the new username instead of an invite id.
Nothing appears in List Pending Invites, so there is nothing to revoke. To take the access back, delete the user.
Inviting an address that already belongs to a user returns 200 with that user's username.
To give a password login to someone outside your identity provider, such as a client who needs only a subaccount, send bypass_sso: true together with subaccounts. The call then creates a regular invite with a registration link. bypass_sso is rejected on a primary-account invite.
Email address of the person to invite. Maximum 512 characters.
The primary-account role to assign. Required unless subaccounts is supplied. admin cannot be set through the API.
Possible Values: developer, reporting, templates, custom
The access policies to grant. Valid only when access_level is custom.
Invite the user with access to one or more subaccounts instead of the primary account. Between 1 and 25 entries. For a full description, see Subaccount invite object.
On an account with single sign-on, create a regular invite with a registration link instead of a single sign-on user. Valid only together with subaccounts.
GET /api/v1/users/pending-invites{
"results": [
{
"id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
"email": "newuser@example.com",
"from": "ada@example.com",
"access_level": "reporting",
"expires": "2024-07-11T00:00:00.000Z"
}
]
}
Returns the invites on your account that nobody has accepted yet, each in the Invite object shape. Expired invites do not appear.
DELETE /api/v1/users/pending-invites/3f2504e0-4f89-41d3-9a0c-0305e82c3301// Empty response body
Revokes a pending invite. Its registration link stops working immediately.
GET /api/v1/users{
"results": [
{
"username": "ada",
"first_name": "Ada",
"last_name": "Lovelace",
"email": "ada@example.com",
"access_level": "admin",
"is_sso": false,
"email_verified": true,
"tfa_enabled": false,
"last_login": "2026-07-28T14:22:31.000Z"
},
{
"username": "katherine",
"first_name": "Katherine",
"last_name": "Johnson",
"email": "katherine@example.com",
"access_level": "custom",
"access_policies": [
"templates/full",
"events/read",
"signals_analytics/full"
],
"is_sso": false,
"email_verified": true,
"tfa_enabled": true,
"last_login": null
}
]
}
Returns the users on your account, each in the User object shape.
GET /api/v1/users/grace{
"results": {
"username": "grace",
"first_name": "Grace",
"last_name": "Hopper",
"email": "grace@example.com",
"access_level": "reporting",
"is_sso": false,
"email_verified": true,
"tfa_enabled": true,
"last_login": "2026-08-02T09:14:05.000Z",
"created": "2015-01-11T08:00:00.000Z",
"updated": "2018-04-11T08:00:00.000Z",
"subaccounts": []
}
}
Returns one user by username, in the User object shape.
PUT /api/v1/users/grace{
"access_level": "developer"
}
{
"results": {
"message": "Successfully modified user grace"
}
}
Changes a primary-account user's role, and the access policies that go with a custom role. No other field on a user can be changed through the API.
The primary-account role to assign. admin cannot be set through the API.
Possible Values: developer, reporting, templates, custom
The access policies to grant. Valid only when access_level is custom.
DELETE /api/v1/users/grace// Empty response body
Deletes a user from your account.
POST /api/v1/users/grace/subaccounts{
"subaccount_id": 123,
"access_level": "subaccount_reporting"
}
{
"results": {
"message": "Subaccount access granted"
}
}
Grants a user access to a subaccount with the role you set. If the user already has access to that subaccount, the call changes their role instead.
The user must already have access to at least one subaccount. This endpoint returns 400 for a primary-account user. To give a new person subaccount access, invite them with a subaccounts array.
The subaccount to grant access to.
The role to grant on the subaccount.
Possible Values: subaccount_reporting, subaccount_developer
DELETE /api/v1/users/grace/subaccounts/123// Empty response body
Removes a user's access to a subaccount.
A subaccount-scoped user must keep access to at least one subaccount. Revoking the last one returns 400. To remove the user from the account entirely, delete the user.