Users

Run in Postman
Import the SparkPost API as a Postman collection

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.

Roles

The access_level field sets a user's role when you invite or update them. The primary-account roles are:

RoleDescription
adminFull access to the account, including user and billing management.
developerAccess to sending and configuration APIs, without account administration.
reportingRead-only access to reporting and analytics.
templatesAccess limited to managing templates.
customA role whose permissions are defined by the access_policies you supply.

Subaccount-scoped users take subaccount_reporting or subaccount_developer instead.

Access policies

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.

PolicyGrants
alerts/fullView and manage alerts.
api_keys/fullManage API keys.
ab_testing/fullView and manage A/B tests of email templates.
domains/fullView and manage sending, bounce, and tracking domains.
events/readView and search message events.
ip_pools/fullView and manage IP pools.
recipient_lists/fullView and manage recipient lists.
recipient_validation/fullValidate email addresses and view recent validations.
seeds/fullView seeding activity and manage seed list settings.
signals_analytics/fullView and manage analytics metrics, dashboards, and reports, including health score, spam traps, engagement recency, and blocklist incidents.
subaccounts/fullManage subaccounts.
suppressions/fullView and manage suppressions.
templates/fullView, manage, and preview email templates and snippets.
users/fullView and manage users.
webhooks/fullView, manage, and test webhooks.

User object

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.

Example

{
  "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": []
}

Attributes

username string

Unique username that identifies the user.

first_name string

The user's first name. Only present when the user has set it.

last_name string

The user's last name. Only present when the user has set it.

email string

The user's email address.

access_level enum

The user's role on the primary account. Absent for subaccount-scoped users.

Possible Values: admin, developer, reporting, templates, custom

access_policies array of strings

The access policies granted to the user. Only present when access_level is custom.

is_sso boolean

Whether the user signs in through single sign-on.

email_verified boolean

Whether the user has verified their email address. Always true for a single sign-on user, because the identity provider confirms the address.

tfa_enabled boolean

Whether the user has two-factor authentication enabled.

last_login string

ISO 8601 timestamp of the user's last sign-in, or null if they have never signed in.

subaccounts array of objects

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.

created string

ISO 8601 timestamp of when the user was created. Returned only by Retrieve a User.

updated string

ISO 8601 timestamp of when the user was last updated. Returned only by Retrieve a User.

Subaccount access object

Each object in a user's subaccounts array describes one subaccount the user has access to, and the user's role on it.

Example

{
  "subaccount_id": 123,
  "subaccount_name": "Joe's Garage",
  "access_level": "subaccount_reporting",
  "status": "active"
}

Attributes

subaccount_id number

The subaccount ID.

subaccount_name string

The subaccount's display name.

access_level enum

The user's role on the subaccount.

Possible Values: subaccount_reporting, subaccount_developer

status enum

The subaccount's status. Returned only by Retrieve a User.

Possible Values: active, suspended, terminated

Invite object

Returned by List Pending Invites.

Example

{
  "id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
  "email": "newuser@example.com",
  "from": "ada@example.com",
  "access_level": "reporting",
  "expires": "2024-07-11T00:00:00.000Z"
}

Attributes

id string

Unique ID of the pending invite.

email string

The email address the invite was sent to.

from string

The email address of the user who created the invite.

access_level enum

The role the user gets when they register.

Possible Values: admin, developer, reporting, templates, custom

access_policies array of strings

The access policies the user gets when they register, if access_level is custom.

subaccounts array of objects

The subaccount access the user gets when they register. See Subaccount invite object. Present instead of access_level for a subaccount-scoped invite.

expires string

ISO 8601 timestamp of when the invite expires.

Subaccount invite object

Each object in the subaccounts array of an Invite a User request grants the invitee access to one subaccount, with the role you set.

Example

{
  "subaccount_id": 123,
  "access_level": "subaccount_reporting"
}

Attributes

subaccount_id number required

The subaccount ID.

access_level enum required

The role to grant on the subaccount.

Possible Values: subaccount_reporting, subaccount_developer

Invite lifecycle

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.

Request

POST /api/v1/users/invite
{
  "email": "newuser@example.com",
  "access_level": "reporting"
}

Response

{
  "results": {
    "id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301"
  }
}
{
  "results": {
    "username": "newuser"
  }
}
{
  "errors": [
    {
      "message": "email is a required parameter",
      "param": "email",
      "value": null
    }
  ]
}
{
  "errors": [
    {
      "message": "An admin-level user cannot be invited through the API."
    }
  ]
}
{
  "errors": [
    {
      "message": "Too many invite requests. Please try again later."
    }
  ]
}

Invite a User

POST/api/v1/users/invite

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.

Request Body

email string required

Email address of the person to invite. Maximum 512 characters.

access_level enum

The primary-account role to assign. Required unless subaccounts is supplied. admin cannot be set through the API.

Possible Values: developer, reporting, templates, custom

access_policies array of strings

The access policies to grant. Valid only when access_level is custom.

subaccounts array of objects

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.

bypass_sso boolean

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.

Request

GET /api/v1/users/pending-invites

Response

{
  "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"
    }
  ]
}

List Pending Invites

GET/api/v1/users/pending-invites

Returns the invites on your account that nobody has accepted yet, each in the Invite object shape. Expired invites do not appear.

Request

DELETE /api/v1/users/pending-invites/3f2504e0-4f89-41d3-9a0c-0305e82c3301

Response

// Empty response body
{
  "errors": [
    {
      "message": "Resource could not be found"
    }
  ]
}

Revoke a Pending Invite

DELETE/api/v1/users/pending-invites/{id}

Parameters

id string required

Revokes a pending invite. Its registration link stops working immediately.

Request

GET /api/v1/users

Response

{
  "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
    }
  ]
}
{
  "errors": [
    {
      "message": "Forbidden"
    }
  ]
}

List Users

GET/api/v1/users

Returns the users on your account, each in the User object shape.

Request

GET /api/v1/users/grace

Response

{
  "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": []
  }
}
  A subaccount-scoped user.

  {
      "results": {
          "username": "joe",
          "first_name": "Joe",
          "last_name": "Mechanic",
          "email": "joe@example.com",
          "is_sso": false,
          "email_verified": true,
          "tfa_enabled": false,
          "last_login": null,
          "created": "2015-01-11T08:00:00.000Z",
          "updated": "2018-04-11T08:00:00.000Z",
          "subaccounts": [
              {
                  "subaccount_id": 123,
                  "subaccount_name": "Joe's Garage",
                  "access_level": "subaccount_reporting",
                  "status": "active"
              }
          ]
      }
  }
{
  "errors": [
    {
      "message": "Resource could not be found"
    }
  ]
}

Retrieve a User

GET/api/v1/users/{username}

Parameters

username string required

Returns one user by username, in the User object shape.

Request

PUT /api/v1/users/grace
{
  "access_level": "developer"
}

Response

{
  "results": {
    "message": "Successfully modified user grace"
  }
}
{
  "errors": [
    {
      "message": "Cannot change the access level of the last admin user on the account."
    }
  ]
}
{
  "errors": [
    {
      "message": "Only access_level and access_policies can be modified through the API."
    }
  ]
}
{
  "errors": [
    {
      "message": "Admin-level access cannot be granted through the API."
    }
  ]
}

Update a User's Role

PUT/api/v1/users/{username}

Parameters

username string required

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.

Request Body

access_level enum

The primary-account role to assign. admin cannot be set through the API.

Possible Values: developer, reporting, templates, custom

access_policies array of strings

The access policies to grant. Valid only when access_level is custom.

Request

DELETE /api/v1/users/grace

Response

// Empty response body
{
  "errors": [
    {
      "message": "Cannot delete the last admin user on the account."
    }
  ]
}
{
  "errors": [
    {
      "message": "Cannot delete current user."
    }
  ]
}
{
  "errors": [
    {
      "message": "Resource could not be found"
    }
  ]
}

Delete a User

DELETE/api/v1/users/{username}

Parameters

username string required

Deletes a user from your account.

Request

POST /api/v1/users/grace/subaccounts
{
  "subaccount_id": 123,
  "access_level": "subaccount_reporting"
}

Response

{
  "results": {
    "message": "Subaccount access granted"
  }
}
{
  "errors": [
    {
      "message": "access_level must be one of: subaccount_reporting, subaccount_developer"
    }
  ]
}
  The user is not subaccount-scoped.

  {
      "errors": [
          {
              "message": "User is not subaccount-scoped"
          }
      ]
  }

Grant Subaccount Access

POST/api/v1/users/{username}/subaccounts

Parameters

username string required

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.

Request Body

subaccount_id number required

The subaccount to grant access to.

access_level enum required

The role to grant on the subaccount.

Possible Values: subaccount_reporting, subaccount_developer

Request

DELETE /api/v1/users/grace/subaccounts/123

Response

// Empty response body
{
  "errors": [
    {
      "message": "Cannot delete last subaccount for user"
    }
  ]
}

Revoke Subaccount Access

DELETE/api/v1/users/{username}/subaccounts/{subaccountId}

Parameters

username string required
subaccountId number required

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.