Stitchflow
EasyPost logo

EasyPost User Management API Guide

API workflow

How to automate user lifecycle operations through APIs with caveats that matter in production.

UpdatedMar 11, 2026

Summary and recommendation

EasyPost's REST API uses HTTP Basic Auth with the API key as the username and an empty password. There are no OAuth scopes - access level is determined entirely by whether you use a Test or Production key, and by whether the authenticating account is a parent or child.

The User object is the core resource for provisioning; it differs structurally between parent accounts (which include a `children` array) and child accounts (which do not).

No SCIM 2.0 endpoint exists. No SSO or IdP integration is documented. All identity lifecycle operations must be driven directly through the EasyPost REST API.

For teams building an identity graph across a multi-tenant architecture, EasyPost's parent/child account model - accessible via `GET /v2/users/{id}/children` with cursor-based pagination - is the only native mechanism for mapping account relationships at scale.

Rate limits are enforced server-side but not publicly documented. HTTP 429 responses should trigger exponential backoff. The `GET /v2/api_keys` endpoint returns all test and production keys for the parent and every child account simultaneously - treat it as a privileged endpoint and restrict access accordingly.

API quick reference

Has user APIYes
Auth methodHTTP Basic Auth (API key as username, empty password)
Base URLOfficial docs
SCIM availableNo
SCIM plan requiredN/A

Authentication

Auth method: HTTP Basic Auth (API key as username, empty password)

Setup steps

  1. Log in to the EasyPost dashboard and navigate to API Keys.
  2. Copy your Test or Production API key.
  3. Pass the API key as the HTTP Basic Auth username with an empty password, or set the Authorization header as 'Authorization: Basic base64(API_KEY:)'.
  4. Use the Production key for live operations; use the Test key for sandbox/testing.

User object / data model

Field Type Description On create On update Notes
id string Unique identifier prefixed with 'user_' auto-generated immutable
object string Always 'User' auto-generated immutable
parent_id string ID of the parent user account; null for top-level accounts set by system immutable
name string Full name of the user or company name required optional
email string Email address for the account required optional Must be unique
phone_number string Contact phone number optional optional
balance string Current account balance (decimal string) auto immutable via API Read-only
recharge_amount string Amount to recharge when balance falls below threshold optional optional
secondary_recharge_amount string Secondary recharge amount optional optional
recharge_threshold string Balance threshold that triggers auto-recharge optional optional
children array List of child User objects under this account auto managed via child user endpoints Only present on parent accounts
api_keys array API key objects associated with the user auto-generated immutable Retrieved via /api_keys endpoint
created_at datetime ISO 8601 timestamp of account creation auto immutable
updated_at datetime ISO 8601 timestamp of last update auto auto

Core endpoints

Retrieve current user

  • Method: GET
  • URL: https://api.easypost.com/v2/users
  • Watch out for: Returns the authenticated user's own record. Use the Production API key to see live data.

Request example

GET /v2/users
Authorization: Basic {base64(API_KEY:)}

Response example

{
  "id": "user_abc123",
  "object": "User",
  "name": "Acme Corp",
  "email": "admin@acme.com",
  "balance": "100.00"
}

Update current user

  • Method: PUT
  • URL: https://api.easypost.com/v2/users/{id}
  • Watch out for: The user ID in the path must match the authenticated user's ID; you cannot update other top-level accounts.

Request example

PUT /v2/users/user_abc123
{
  "user": {
    "name": "Acme Corp Updated",
    "phone_number": "555-1234"
  }
}

Response example

{
  "id": "user_abc123",
  "name": "Acme Corp Updated",
  "phone_number": "555-1234"
}

Create child user

  • Method: POST
  • URL: https://api.easypost.com/v2/users
  • Watch out for: Child users are sub-accounts under the authenticated parent. They share the parent's carrier accounts unless configured separately.

Request example

POST /v2/users
{
  "user": {
    "name": "Child Account",
    "email": "child@acme.com"
  }
}

Response example

{
  "id": "user_child456",
  "object": "User",
  "parent_id": "user_abc123",
  "name": "Child Account",
  "email": "child@acme.com"
}

Retrieve child user

  • Method: GET
  • URL: https://api.easypost.com/v2/users/{id}
  • Watch out for: Must authenticate as the parent account to retrieve child user details.

Request example

GET /v2/users/user_child456
Authorization: Basic {base64(PARENT_API_KEY:)}

Response example

{
  "id": "user_child456",
  "parent_id": "user_abc123",
  "name": "Child Account"
}

Delete child user

  • Method: DELETE
  • URL: https://api.easypost.com/v2/users/{id}
  • Watch out for: Only child users can be deleted via API. Top-level accounts cannot be deleted through the API.

Request example

DELETE /v2/users/user_child456
Authorization: Basic {base64(PARENT_API_KEY:)}

Response example

HTTP 204 No Content

Retrieve API keys

  • Method: GET
  • URL: https://api.easypost.com/v2/api_keys
  • Watch out for: Returns both test and production keys for the authenticated user and all child accounts. Guard this endpoint carefully.

Request example

GET /v2/api_keys
Authorization: Basic {base64(API_KEY:)}

Response example

{
  "id": "user_abc123",
  "keys": [
    {"object": "ApiKey", "key": "EZAK...", "mode": "production"}
  ],
  "children": []
}

Update child user

  • Method: PUT
  • URL: https://api.easypost.com/v2/users/{id}
  • Watch out for: Authenticate as the parent account when updating child user fields.

Request example

PUT /v2/users/user_child456
{
  "user": {
    "recharge_amount": "50.00",
    "recharge_threshold": "10.00"
  }
}

Response example

{
  "id": "user_child456",
  "recharge_amount": "50.00",
  "recharge_threshold": "10.00"
}

List child users

  • Method: GET
  • URL: https://api.easypost.com/v2/users/{id}/children
  • Watch out for: Pagination uses cursor-based before_id parameter. has_more indicates additional pages.

Request example

GET /v2/users/user_abc123/children?page_size=20
Authorization: Basic {base64(API_KEY:)}

Response example

{
  "children": [
    {"id": "user_child456", "name": "Child Account"}
  ],
  "has_more": false
}

Rate limits, pagination, and events

  • Rate limits: EasyPost does not publish explicit per-plan rate limits in its public documentation. Rate limiting exists and is enforced server-side; exceeding limits returns HTTP 429.
  • Rate-limit headers: No
  • Retry-After header: Yes
  • Rate-limit notes: HTTP 429 is returned when rate limits are exceeded. Retry-After header may be present. Contact EasyPost support for specific limits on high-volume accounts.
  • Pagination method: cursor
  • Default page size: 20
  • Max page size: 100
  • Pagination pointer: page_size / before_id
Plan Limit Concurrent
All plans Not publicly documented 0
  • Webhooks available: Yes
  • Webhook notes: EasyPost supports webhooks for shipment and tracker events. There are no dedicated user-management webhook events (e.g., user created/deleted).
  • Alternative event strategy: Poll GET /v2/users/{id}/children for child account changes.
  • Webhook events: tracker.created, tracker.updated, payment.created, refund.successful, batch.created, batch.updated, scan_form.created, insurance.purchased, insurance.cancelled, insurance.failed

SCIM API status

  • SCIM available: No
  • SCIM version: Not documented
  • Plan required: N/A
  • Endpoint: Not documented

Limitations:

  • EasyPost does not offer a SCIM 2.0 API.
  • No SSO/IdP integration (Okta, Entra, Google Workspace) is documented.
  • User provisioning must be done via the EasyPost REST API directly.

Common scenarios

Three automation scenarios are well-supported by the API. First, tenant provisioning: authenticate as the parent, POST to /v2/users with name and email, store the returned id and auto-generated API keys, then optionally set recharge_amount and recharge_threshold via PUT. Child accounts share the parent's billing by default, so recharge configuration is a required step in any production provisioning flow.

Second, API key auditing: a single GET /v2/api_keys call returns keys for the parent and all children. Iterate the children array to map each child id to its test and production keys. This endpoint's broad scope makes it a high-value target - restrict it at the application layer in multi-tenant deployments.

Third, deprovisioning: confirm the child user ID via GET, then DELETE /v2/users/{child_id}. A 204 response confirms permanent removal. This operation is irreversible and removes all associated shipment history and API keys for the child account - there is no soft-delete or recovery path via API.

Provision a child account for a new tenant

  1. Authenticate with the parent account's Production API key.
  2. POST /v2/users with name and email to create the child user.
  3. Store the returned child user id and auto-generated API keys.
  4. Optionally PUT /v2/users/{child_id} to set recharge_amount and recharge_threshold.
  5. Distribute the child's API key to the tenant for their own API calls.

Watch out for: Child accounts share the parent's billing by default. Ensure recharge thresholds are set to avoid unexpected charges to the parent balance.

Retrieve and audit all child API keys

  1. Authenticate with the parent account's Production API key.
  2. GET /v2/api_keys to retrieve keys for the parent and all children.
  3. Iterate the children array in the response to map each child ID to their test/production keys.
  4. Log or store keys securely for audit purposes.

Watch out for: This single endpoint exposes all child keys simultaneously. Limit who can call this endpoint in your application.

Deprovision a child account

  1. Authenticate with the parent account's Production API key.
  2. Confirm the child user ID via GET /v2/users/{child_id}.
  3. DELETE /v2/users/{child_id} to permanently remove the child account.
  4. Verify HTTP 204 response confirming deletion.

Watch out for: Deletion is permanent and cannot be undone via API. All shipment history and API keys for the child are removed.

Why building this yourself is a trap

The primary integration trap is assuming that removing a dashboard team member completes the offboarding process. It does not. API keys issued to or used by that member remain active until explicitly rotated or deleted via the API Keys section.

There is no automated key revocation tied to team member removal, and no audit log to surface which keys a removed member had access to.

A second trap is pagination: EasyPost uses cursor-based pagination (before_id), not offset. Any integration that assumes offset pagination will silently miss records after the first page. Store the last returned id and pass it as before_id on subsequent requests; check has_more to determine whether additional pages exist.

For teams building on top of EasyPost with an MCP server with 60+ deep IT/identity integrations, the absence of SCIM and webhook coverage for user lifecycle events (no user.created or user.deleted events exist) means child account state must be tracked by polling GET /v2/users/{id}/children rather than reacting to push notifications. Design your sync layer accordingly.

Automate EasyPost 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.

Every app coverage, including apps without APIs
60+ app integrations plus browser automation for apps without APIs
IT graph reconciliation across apps and your IdP
Less than a week to launch, maintained as APIs and admin consoles change
SOC 2 Type II. ~2 hours of your team's time

UpdatedMar 11, 2026

* Details sourced from official product documentation and admin references.

Keep exploring

Related apps

Abnormal Security logo

Abnormal Security

API Only
AutomationAPI only
Last updatedMar 2026

Abnormal Security is an enterprise email security platform focused on detecting and investigating threats such as phishing, account takeover (ATO), and vendor email compromise. It does not support SCIM provisioning, which means every app in your stack

ActiveCampaign logo

ActiveCampaign

API Only
AutomationAPI only
Last updatedFeb 2026

ActiveCampaign uses a group-based permission model: every user belongs to exactly one group, and all feature-area access (Contacts, Campaigns, Automations, Deals, Reports, Templates) is configured at the group level, not per individual. The default Adm

ADP logo

ADP

API Only
AutomationAPI only
Last updatedFeb 2026

ADP Workforce Now is a mid-market to enterprise HCM platform that serves as the HR source of record for employee data — payroll, benefits, time, and talent. User access is governed by a hybrid permission model: predefined security roles (Security Maste