Stitchflow
Square logo

Square User Management API Guide

API workflow

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

UpdatedMar 16, 2026

Summary and recommendation

Square's Team API (base URL: `https://connect.squareup.com/v2`) supports create, retrieve, update, search, bulk-create, and status-based deactivation of team members.

Auth is OAuth 2.0 Bearer token or personal access token;

required scopes are `EMPLOYEES_READ` and `EMPLOYEES_WRITE` for team member lifecycle operations.

Square does not expose a native SCIM 2.0 endpoint - IdP integrations (Okta, Entra ID, OneLogin) cover SSO/SAML only, not automated provisioning.

Any identity graph that needs to reflect Square team member state must be built and maintained against the Team API directly.

Key structural constraints to wire into your integration: - `POST /v2/team-members/search` is the only way to list or filter team members; there is no `GET /v2/team-members` collection endpoint. - All update operations (`PUT /v2/team-members/{id}`, `PUT /v2/team-members/{id}/wage-setting`) use full-replace semantics - omitting fields clears them. - Hard deletion is not supported; set `status: INACTIVE` to offboard. - `idempotency_key` is required on create operations and is valid for 24 hours.

API quick reference

Has user APIYes
Auth methodOAuth 2.0 (Bearer token) or personal access token
Base URLOfficial docs
SCIM availableNo

Authentication

Auth method: OAuth 2.0 (Bearer token) or personal access token

Setup steps

  1. Register an application at https://developer.squareup.com/apps to obtain a client_id and client_secret.
  2. Direct the merchant/user to Square's OAuth authorization URL: https://connect.squareup.com/oauth2/authorize with required scopes.
  3. Exchange the returned authorization code for an access token via POST https://connect.squareup.com/oauth2/token.
  4. Include the access token in all API requests as: Authorization: Bearer {access_token}.
  5. For personal access tokens (own account only), retrieve from the Developer Dashboard and use directly as the Bearer token.

Required scopes

Scope Description Required for
EMPLOYEES_READ Read team member profiles and employment details. Listing and retrieving team members
EMPLOYEES_WRITE Create and update team member profiles. Creating, updating, or deactivating team members
TIMECARDS_READ Read shift and timecard data for team members. Reading shift/timecard records
TIMECARDS_WRITE Create and update shift and timecard data. Writing shift/timecard records

User object / data model

Field Type Description On create On update Notes
id string Unique Square-assigned team member ID. auto-generated immutable Format: TM{alphanumeric}
reference_id string Optional external/third-party identifier for the team member. optional updatable Useful for syncing with external HR systems.
is_owner boolean Whether the team member is the account owner. auto-set immutable Only one team member per account can be the owner.
status enum Employment status: ACTIVE or INACTIVE. required updatable Set to INACTIVE to deactivate (soft delete).
given_name string Team member's first name. optional updatable
family_name string Team member's last name. optional updatable
email_address string Team member's email address. optional updatable Used for Square account login if team member has a Square account.
phone_number string Team member's phone number in E.164 format. optional updatable
created_at string (RFC 3339) Timestamp when the team member record was created. auto-generated immutable
updated_at string (RFC 3339) Timestamp of the last update to the team member record. auto-generated auto-updated
assigned_locations object Locations the team member is assigned to. Contains assignment_type (ALL_CURRENT_AND_FUTURE_LOCATIONS or EXPLICIT_LOCATIONS) and location_ids array. optional updatable
wage_setting object Wage and job assignment details. Contains job_assignments array and is_overtime_exempt boolean. optional (set via separate endpoint) updatable via UpdateWageSetting Managed via /v2/team-members/{id}/wage-setting endpoint.

Core endpoints

Create Team Member

  • Method: POST
  • URL: https://connect.squareup.com/v2/team-members
  • Watch out for: idempotency_key is required to prevent duplicate creation on retries. Must be unique per request.

Request example

POST /v2/team-members
{
  "idempotency_key": "uuid-here",
  "team_member": {
    "given_name": "Jane",
    "family_name": "Doe",
    "email_address": "jane@example.com",
    "status": "ACTIVE"
  }
}

Response example

{
  "team_member": {
    "id": "TMabc123",
    "given_name": "Jane",
    "family_name": "Doe",
    "status": "ACTIVE",
    "created_at": "2024-01-01T00:00:00Z"
  }
}

Retrieve Team Member

  • Method: GET
  • URL: https://connect.squareup.com/v2/team-members/{team_member_id}
  • Watch out for: Returns 404 if the team member ID does not exist in the authenticated merchant's account.

Request example

GET /v2/team-members/TMabc123

Response example

{
  "team_member": {
    "id": "TMabc123",
    "given_name": "Jane",
    "family_name": "Doe",
    "status": "ACTIVE",
    "email_address": "jane@example.com"
  }
}

Update Team Member

  • Method: PUT
  • URL: https://connect.squareup.com/v2/team-members/{team_member_id}
  • Watch out for: This is a full PUT (replace), not a PATCH. Omitting fields may clear existing values. Send the full team_member object.

Request example

PUT /v2/team-members/TMabc123
{
  "team_member": {
    "given_name": "Jane",
    "family_name": "Smith",
    "status": "ACTIVE"
  }
}

Response example

{
  "team_member": {
    "id": "TMabc123",
    "given_name": "Jane",
    "family_name": "Smith",
    "updated_at": "2024-06-01T12:00:00Z"
  }
}

Deactivate Team Member

  • Method: PUT
  • URL: https://connect.squareup.com/v2/team-members/{team_member_id}
  • Watch out for: Square does not support hard deletion of team members via API. Set status to INACTIVE to deactivate.

Request example

PUT /v2/team-members/TMabc123
{
  "team_member": {
    "status": "INACTIVE"
  }
}

Response example

{
  "team_member": {
    "id": "TMabc123",
    "status": "INACTIVE",
    "updated_at": "2024-06-01T13:00:00Z"
  }
}

Search Team Members

  • Method: POST
  • URL: https://connect.squareup.com/v2/team-members/search
  • Watch out for: Search uses POST, not GET. Cursor-based pagination; pass cursor from response to retrieve next page.

Request example

POST /v2/team-members/search
{
  "query": {
    "filter": {
      "status": "ACTIVE",
      "location_ids": ["LXYZ"]
    }
  },
  "limit": 50
}

Response example

{
  "team_members": [...],
  "cursor": "next_page_cursor_string",
  "errors": []
}

Bulk Create Team Members

  • Method: POST
  • URL: https://connect.squareup.com/v2/team-members/bulk-create
  • Watch out for: Request body uses a map keyed by client-defined idempotency keys. Partial failures are returned per-key in the response.

Request example

POST /v2/team-members/bulk-create
{
  "team_members": {
    "key1": {"team_member": {"given_name": "Alice", "status": "ACTIVE"}},
    "key2": {"team_member": {"given_name": "Bob", "status": "ACTIVE"}}
  }
}

Response example

{
  "team_members": {
    "key1": {"team_member": {"id": "TM001", ...}},
    "key2": {"team_member": {"id": "TM002", ...}}
  }
}

Retrieve Wage Setting

  • Method: GET
  • URL: https://connect.squareup.com/v2/team-members/{team_member_id}/wage-setting
  • Watch out for: Wage settings are managed separately from the core team member object.

Request example

GET /v2/team-members/TMabc123/wage-setting

Response example

{
  "wage_setting": {
    "team_member_id": "TMabc123",
    "job_assignments": [{"job_title": "Cashier", "pay_type": "HOURLY"}],
    "is_overtime_exempt": false
  }
}

Update Wage Setting

  • Method: PUT
  • URL: https://connect.squareup.com/v2/team-members/{team_member_id}/wage-setting
  • Watch out for: Full replace semantics. All job_assignments must be included; omitted assignments will be removed.

Request example

PUT /v2/team-members/TMabc123/wage-setting
{
  "wage_setting": {
    "job_assignments": [{"job_title": "Manager", "pay_type": "SALARY"}],
    "is_overtime_exempt": true
  }
}

Response example

{
  "wage_setting": {
    "team_member_id": "TMabc123",
    "job_assignments": [{"job_title": "Manager", "pay_type": "SALARY"}],
    "is_overtime_exempt": true
  }
}

Rate limits, pagination, and events

  • Rate limits: Square enforces per-endpoint rate limits. The Team API allows up to 35 requests per second per application by default. Limits vary by endpoint category.
  • Rate-limit headers: Yes
  • Retry-After header: No
  • Rate-limit notes: Square returns HTTP 429 when rate limits are exceeded. The X-RateLimit-Limit and X-RateLimit-Remaining headers are documented. Retry-After header behavior is not explicitly documented in official sources.
  • Pagination method: cursor
  • Default page size: 100
  • Max page size: 200
  • Pagination pointer: cursor
Plan Limit Concurrent
Default (all apps) 35 requests/second (Team API endpoints) 0
  • Webhooks available: Yes
  • Webhook notes: Square supports webhooks for team member events. Subscriptions are configured in the Developer Dashboard or via the Webhooks API. Payloads are delivered via HTTPS POST to a registered endpoint.
  • Alternative event strategy: Poll the Search Team Members endpoint (POST /v2/team-members/search) for change detection if webhooks are not feasible.
  • Webhook events: team_member.created, team_member.updated, team_member.wage_setting.updated

SCIM API status

  • SCIM available: No
  • SCIM version: Not documented
  • Plan required: Not documented
  • Endpoint: Not documented

Limitations:

  • Square does not offer a native SCIM 2.0 endpoint as of the current documentation.
  • IdP integrations (Okta, Entra ID, OneLogin) are available but use SSO/SAML, not SCIM provisioning.
  • Automated provisioning must be implemented via the Team API directly.

Common scenarios

Three integration scenarios with explicit caveats:

Onboard: POST /v2/team-members with idempotency_key, identity fields, status: ACTIVE, and assigned_locations.

Capture the returned team_member.id.

Wage settings cannot be included in the creation body - issue a separate PUT /v2/team-members/{id}/wage-setting after creation.

Use reference_id to store your internal HR system's identifier on the Square object for identity graph correlation.

Sync active members: POST /v2/team-members/search with filter.status: ACTIVE and target location_ids.

Default page size is 100, max is 200;

iterate using the cursor field until no cursor is returned.

OAuth tokens are scoped per merchant - confirm the token covers the correct location_ids before filtering.

Offboard: PUT /v2/team-members/{id} with the full team member object and status: INACTIVE.

Confirm status: INACTIVE and updated_at in the response.

Subscribe to the team_member.updated webhook for event-driven confirmation.

INACTIVE records persist in Square's system and are reactivatable - your identity graph must treat INACTIVE as the terminal offboarded state, not as deletion.

Onboard a new employee

  1. POST /v2/team-members with idempotency_key, given_name, family_name, email_address, status=ACTIVE, and assigned_locations.
  2. Capture the returned team_member.id.
  3. PUT /v2/team-members/{id}/wage-setting to assign job title, pay type, and overtime exemption status.
  4. Optionally store the Square team_member.id mapped to your internal HR system ID via reference_id.

Watch out for: Wage settings must be set in a separate API call after team member creation; they cannot be included in the initial POST body.

Sync active team members to an external system

  1. POST /v2/team-members/search with filter status=ACTIVE and desired location_ids.
  2. Iterate through returned team_members array.
  3. If a cursor is present in the response, repeat the POST with the cursor value to retrieve the next page.
  4. Continue until no cursor is returned in the response.

Watch out for: Default page size is 100, max is 200. Large teams require multiple paginated requests. There is no GET list endpoint.

Offboard (deactivate) a departing employee

  1. Identify the team member's Square ID (from your system's stored reference or via search by email/reference_id).
  2. PUT /v2/team-members/{id} with the full team_member object and status set to INACTIVE.
  3. Verify the response confirms status=INACTIVE and updated_at timestamp.
  4. Optionally subscribe to the team_member.updated webhook to confirm the status change event is received.

Watch out for: Hard deletion is not available. INACTIVE team members remain in Square's system and can be reactivated. Ensure your system treats INACTIVE as offboarded.

Why building this yourself is a trap

The most consequential API traps for integration builders:

  • Full-replace PUT: Sending a partial update object will silently clear omitted fields. Always retrieve the current object first, mutate the target fields, and PUT the complete payload.
  • No SCIM, no auto-provisioning: Because Square has no SCIM endpoint, any identity graph built on top of Square - including an MCP server with 60+ deep IT/identity integrations - must implement its own create/deactivate lifecycle logic against the Team API. There is no delegated provisioning path.
  • API versioning is date-based: Requests without a Square-Version header fall back to the application's default version set in the Developer Dashboard. Pin the version header explicitly (e.g., Square-Version: 2024-01-17) to avoid silent behavior changes on version rollover.
  • Sandbox isolation: The sandbox base URL (https://connect.squareupsandbox.com/v2) is distinct from production. Misconfigured environments will return 401s or operate against test data silently.
  • Rate limits: The Team API allows up to 35 requests/second per application. HTTP 429 is returned on breach; X-RateLimit-Limit and X-RateLimit-Remaining headers are available, but Retry-After header behavior is not explicitly documented - implement exponential backoff.

Automate Square 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 16, 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