Team & Roles

Manage team members, roles, and permissions

GET /admin/api/me

Returns the current authenticated user's info and effective permissions. Owners get all permission codes.

GET /admin/api/permissions

List all available permission codes with their groups and descriptions. Any authenticated admin can access this.

GET /admin/api/team

List admin users with pagination, search, role filtering, and sorting.

POST /admin/api/team

Invite (create) a new admin user. The password is hashed with Argon2 before storage.

GET /admin/api/team/{id}

Get a single admin user by ID.

PUT /admin/api/team/{id}

Update an admin user's name and role assignment.

DELETE /admin/api/team/{id}

Remove an admin user. You cannot delete your own account.

GET /admin/api/roles

List all roles with their assigned permissions.

POST /admin/api/roles

Create a new role with a set of permissions.

GET /admin/api/roles/{id}

Get a single role with its permissions.

PUT /admin/api/roles/{id}

Update a role's name and permissions. Replaces the entire permission set.

DELETE /admin/api/roles/{id}

Delete a role. Users assigned this role are promoted to Owner (role_id set to NULL).

GET /admin/api/personal-access-tokens

List the caller's personal access tokens. Filtered to the authenticated user -- you can never see another user's tokens.

POST /admin/api/personal-access-tokens

Create a new personal access token. Cookie-only -- PAT-authenticated callers receive 403. The plaintext token is returned exactly once. Max 20 active tokens per user.

DELETE /admin/api/personal-access-tokens/{id}

Revoke a personal access token. You can only revoke your own tokens -- attempts to revoke another user's token return 404.

GET /admin/api/me

Returns the current authenticated user's info and effective permissions. Owners get all permission codes.

Response 200

{
  "id": 1,
  "email": "owner@myshop.com",
  "name": "Jane Smith",
  "is_owner": true,
  "role_id": null,
  "role_name": null,
  "permissions": [
    "dashboard.view",
    "products.view",
    "products.create",
    "products.edit",
    "products.delete",
    "orders.view",
    "orders.edit",
    "settings.view",
    "settings.edit",
    "users.view",
    "users.create",
    "users.edit",
    "users.delete",
    "roles.view",
    "roles.create",
    "roles.edit",
    "roles.delete",
    "subscriptions.view",
    "subscriptions.edit"
  ]
}

Example

curl "https://yourshop.zeroshop.io/admin/api/me" \
  -H "Authorization: Bearer zspat_..."
GET /admin/api/permissions

List all available permission codes with their groups and descriptions. Any authenticated admin can access this.

Response 200

[
  {
    "code": "dashboard.view",
    "group": "Dashboard",
    "description": "View dashboard metrics"
  },
  {
    "code": "products.view",
    "group": "Products",
    "description": "View products"
  },
  {
    "code": "products.create",
    "group": "Products",
    "description": "Create products"
  },
  {
    "code": "orders.view",
    "group": "Orders",
    "description": "View orders"
  },
  {
    "code": "settings.view",
    "group": "Settings",
    "description": "View settings"
  },
  {
    "code": "settings.edit",
    "group": "Settings",
    "description": "Edit settings"
  }
]

Example

curl "https://yourshop.zeroshop.io/admin/api/permissions" \
  -H "Authorization: Bearer zspat_..."
GET /admin/api/team

List admin users with pagination, search, role filtering, and sorting.

Parameters

Name Type Required Description
page integer optional Page number, 1-indexed (default: 1)
per_page integer optional Items per page, 1-100 (default: 20)
search string optional Text search on name or email
role string optional Filter by role: "owner" for owners, or a numeric role ID
sort string optional Sort field with optional - prefix for descending. Valid: name, email, created_at. Default: created_at

Response 200

{
  "data": [
    {
      "id": 1,
      "email": "owner@myshop.com",
      "name": "Jane Smith",
      "is_owner": true,
      "role_id": null,
      "role_name": null,
      "created_at": "2025-10-01T10:00:00Z"
    },
    {
      "id": 2,
      "email": "editor@myshop.com",
      "name": "Bob Jones",
      "is_owner": false,
      "role_id": 1,
      "role_name": "Editor",
      "created_at": "2025-11-05T14:00:00Z"
    }
  ],
  "page": 1,
  "per_page": 20,
  "total": 2,
  "total_pages": 1
}

Example

curl "https://yourshop.zeroshop.io/admin/api/team?page=1&per_page=20&sort=-created_at" \
  -H "Authorization: Bearer zspat_..."
POST /admin/api/team

Invite (create) a new admin user. The password is hashed with Argon2 before storage.

Request Body

{
  "email": "newadmin@myshop.com",
  "name": "Alice Lee",
  "password": "securePass123!",
  "role_id": 1
}

Response 201

{
  "id": 3,
  "email": "newadmin@myshop.com",
  "name": "Alice Lee",
  "is_owner": false,
  "role_id": 1,
  "role_name": "Editor",
  "created_at": "2025-11-20T14:00:00Z"
}

Example

curl -X POST "https://yourshop.zeroshop.io/admin/api/team" \
  -H "Authorization: Bearer zspat_..." \
  -H "Content-Type: application/json" \
  -d '{"email": "newadmin@myshop.com", "name": "Alice Lee", "password": "securePass123!", "role_id": 1}'
GET /admin/api/team/{id}

Get a single admin user by ID.

Parameters

Name Type Required Description
id integer required Admin user ID

Response 200

{
  "id": 2,
  "email": "editor@myshop.com",
  "name": "Bob Jones",
  "is_owner": false,
  "role_id": 1,
  "role_name": "Editor",
  "created_at": "2025-11-05T14:00:00Z"
}

Example

curl "https://yourshop.zeroshop.io/admin/api/team/2" \
  -H "Authorization: Bearer zspat_..."
PUT /admin/api/team/{id}

Update an admin user's name and role assignment.

Parameters

Name Type Required Description
id integer required Admin user ID

Request Body

{
  "name": "Bob Jones Jr.",
  "role_id": 2
}

Response 204

Example

curl -X PUT "https://yourshop.zeroshop.io/admin/api/team/2" \
  -H "Authorization: Bearer zspat_..." \
  -H "Content-Type: application/json" \
  -d '{"name": "Bob Jones Jr.", "role_id": 2}'
DELETE /admin/api/team/{id}

Remove an admin user. You cannot delete your own account.

Parameters

Name Type Required Description
id integer required Admin user ID

Response 204

Example

curl -X DELETE "https://yourshop.zeroshop.io/admin/api/team/3" \
  -H "Authorization: Bearer zspat_..."
GET /admin/api/roles

List all roles with their assigned permissions.

Response 200

{
  "roles": [
    {
      "id": 1,
      "name": "Editor",
      "permissions": [
        "products.view",
        "products.create",
        "products.edit",
        "orders.view"
      ],
      "created_at": "2025-10-15T09:00:00Z"
    },
    {
      "id": 2,
      "name": "Viewer",
      "permissions": [
        "dashboard.view",
        "products.view",
        "orders.view"
      ],
      "created_at": "2025-10-15T09:05:00Z"
    }
  ]
}

Example

curl "https://yourshop.zeroshop.io/admin/api/roles" \
  -H "Authorization: Bearer zspat_..."
POST /admin/api/roles

Create a new role with a set of permissions.

Request Body

{
  "name": "Editor",
  "permissions": [
    "products.view",
    "products.create",
    "products.edit",
    "orders.view"
  ]
}

Response 201

{
  "id": 3,
  "name": "Editor",
  "permissions": [
    "products.view",
    "products.create",
    "products.edit",
    "orders.view"
  ],
  "created_at": ""
}

Example

curl -X POST "https://yourshop.zeroshop.io/admin/api/roles" \
  -H "Authorization: Bearer zspat_..." \
  -H "Content-Type: application/json" \
  -d '{"name": "Editor", "permissions": ["products.view", "products.create", "products.edit", "orders.view"]}'
GET /admin/api/roles/{id}

Get a single role with its permissions.

Parameters

Name Type Required Description
id integer required Role ID

Response 200

{
  "id": 1,
  "name": "Editor",
  "permissions": [
    "products.view",
    "products.create",
    "products.edit",
    "orders.view"
  ],
  "created_at": "2025-10-15T09:00:00Z"
}

Example

curl "https://yourshop.zeroshop.io/admin/api/roles/1" \
  -H "Authorization: Bearer zspat_..."
PUT /admin/api/roles/{id}

Update a role's name and permissions. Replaces the entire permission set.

Parameters

Name Type Required Description
id integer required Role ID

Request Body

{
  "name": "Senior Editor",
  "permissions": [
    "products.view",
    "products.create",
    "products.edit",
    "products.delete",
    "orders.view",
    "orders.edit"
  ]
}

Response 204

Example

curl -X PUT "https://yourshop.zeroshop.io/admin/api/roles/1" \
  -H "Authorization: Bearer zspat_..." \
  -H "Content-Type: application/json" \
  -d '{"name": "Senior Editor", "permissions": ["products.view", "products.create", "products.edit", "products.delete"]}'
DELETE /admin/api/roles/{id}

Delete a role. Users assigned this role are promoted to Owner (role_id set to NULL).

Parameters

Name Type Required Description
id integer required Role ID

Response 204

Example

curl -X DELETE "https://yourshop.zeroshop.io/admin/api/roles/1" \
  -H "Authorization: Bearer zspat_..."
GET /admin/api/personal-access-tokens

List the caller's personal access tokens. Filtered to the authenticated user -- you can never see another user's tokens.

Response 200

{
  "tokens": [
    {
      "id": 1,
      "name": "CI pipeline",
      "prefix": "a1b2c3d4e5f6",
      "created_at": "2025-11-01T10:00:00Z",
      "last_used_at": "2025-11-20T14:30:00Z",
      "expires_at": "2026-01-29T10:00:00Z",
      "revoked_at": null
    },
    {
      "id": 2,
      "name": "Local dev",
      "prefix": "g7h8i9j0k1l2",
      "created_at": "2025-11-10T08:00:00Z",
      "last_used_at": null,
      "expires_at": null,
      "revoked_at": null
    }
  ]
}

Example

curl "https://yourshop.zeroshop.io/admin/api/personal-access-tokens" \
  -H "Authorization: Bearer zspat_..."
POST /admin/api/personal-access-tokens

Create a new personal access token. Cookie-only -- PAT-authenticated callers receive 403. The plaintext token is returned exactly once. Max 20 active tokens per user.

Request Body

{
  "name": "CI pipeline",
  "expires_in_days": 90
}

Response 201

{
  "id": 3,
  "name": "CI pipeline",
  "token": "zspat_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w",
  "prefix": "a1b2c3d4e5f6",
  "expires_at": "2026-02-18T10:00:00Z"
}

Example

curl -X POST "https://yourshop.zeroshop.io/admin/api/personal-access-tokens" \
  -H "Cookie: zeroshop_admin_jwt=..." \
  -H "Content-Type: application/json" \
  -d '{"name": "CI pipeline", "expires_in_days": 90}'
DELETE /admin/api/personal-access-tokens/{id}

Revoke a personal access token. You can only revoke your own tokens -- attempts to revoke another user's token return 404.

Parameters

Name Type Required Description
id integer required Token ID

Response 204

Example

curl -X DELETE "https://yourshop.zeroshop.io/admin/api/personal-access-tokens/1" \
  -H "Authorization: Bearer zspat_..."

We value your privacy

We use cookies for essential site functionality and, with your consent, analytics to understand how our platform is used. No personal data is shared with third parties. See our Privacy Policy for details.