Users

Run in Postman
Import the SparkPost API as a Postman collection

Manage the users on your account: list, 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, and nothing else. Supply them as an array of policy names. The field is only valid 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.

Every user is scoped either to the account or to one or more subaccounts. An account-scoped 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.

last_name string

The user's last name.

email string

The user's email address.

access_level enum

The user's role on the 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 when access_level is custom.

is_sso boolean

Whether the user signs in via single sign-on.

email_verified boolean

Whether the user has verified their email 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 can reach, and their role on each. See Subaccount access object. Returned by Retrieve a User only, and empty for an account-scoped user.

created string

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

updated string

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

Subaccount access object

Each object in a user's subaccounts array describes one subaccount the user can reach, and the access level they hold 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 access level on the subaccount.

Possible Values: subaccount_reporting, subaccount_developer

status enum

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

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": 1720656000
}

Attributes

id string

Unique ID for the pending invite. Use it to revoke the 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 takes on when they register.

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

access_policies array of strings

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

subaccounts array of objects

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

expires number

Unix timestamp, in epoch seconds, at which the invitation expires.

Subaccount invite object

Each object in the subaccounts array of an Invite a User request grants the invitee access to one subaccount.

Example

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

Attributes

subaccount_id number required

The subaccount ID.

access_level enum required

The access level to grant on the subaccount.

Possible Values: subaccount_reporting, subaccount_developer

Invite lifecycle

Invitations expire after three days. The registration link then stops working and the invitation drops off List Pending Invites.

To give someone another chance to register, invite the same email address again. That creates a second, independent invitation with its own expiry, and 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"
  }
}
{
  "errors": [
    {
      "message": "email is a required parameter",
      "param": "email",
      "value": null
    }
  ]
}
{
  "errors": [
    {
      "message": "API keys cannot invite an admin-level user."
    }
  ]
}
{
  "errors": [
    {
      "message": "Too many invite requests. Please try again later."
    }
  ]
}

Invite a User

POST/api/v1/users/invite

Creates an invitation and emails a registration link to the address you supply. The invitee follows the link, sets their own password, and takes the role you named in access_level.

Send access_level to invite a primary-account user, or subaccounts to invite a subaccount-scoped one. A subaccounts invite does not need a top-level access_level.

The response contains the invite id, which you use to list and revoke the invitation.

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 is not available to API keys.

Possible Values: developer, reporting, templates, custom

access_policies array of strings

The access policies to grant. Only valid 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.

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

List Pending Invites

GET/api/v1/users/pending-invites

Returns the invitations on your account that nobody has accepted yet. Expired invitations do not appear.

Request

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

Response

// Empty response body
{
  "errors": [
    {
      "message": "User invite ID does not exist"
    }
  ]
}

Revoke a Pending Invite

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

Parameters

id string required

Revokes a pending invitation. 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.

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": "User not 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": "API keys may only modify access_level and access_policies."
    }
  ]
}

Update a User's Role

PUT/api/v1/users/{username}

Parameters

username string required

Request Body

access_level enum

The primary-account role to assign.

Possible Values: developer, reporting, templates, custom

access_policies array of strings

The access policies to grant. Only valid 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": "User does not exist"
    }
  ]
}

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": "Invalid user"
          }
      ]
  }

Grant Subaccount Access

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

Parameters

username string required

Grants a user access to a subaccount at the given access level. If the user already has access to that subaccount, the call updates their access level instead.

The user must already have access to at least one subaccount. Calling this endpoint for a primary-account user returns 400. 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 access level 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.