> ## Documentation Index
> Fetch the complete documentation index at: https://docs.shorpay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Public API

> Integrate with your Shor workspace through the versioned API.

The public API is available to enabled employer workspaces. Ask Shor to enable your workspace before connecting an integration. Administrators create credentials in **Settings → API keys**. Copy the secret when it is shown; it cannot be retrieved later. Choose only the scopes the integration needs and an expiry date. Rotate before expiry, update your secret store, then revoke the old credential. Never put keys in browser code or source control.

Use the API base URL supplied for your environment. All resource paths start with `/v1`. Test credentials are accepted only by the matching test environment. The current contract is available without authentication at `/v1/openapi.json`; a [downloadable reference](/api-reference/openapi.json) is included here.

Connecting an AI assistant instead? Start with [Connect AI assistants](/employer/ai-assistants). The [MCP tool reference](/developers/mcp) maps every supported tool to its HTTP route, inputs, scopes, and confirmation requirements.

```bash theme={null}
curl "$SHOR_API_URL/v1/business" \
  -H "Authorization: Bearer $SHOR_API_KEY"
```

Keys act as the membership that created them. Leaving the workspace revokes access permanently. A role change applies immediately, including to retries. Admins can manage keys; members can read and create drafts when granted the corresponding scopes; viewers can only read. Timesheet and milestone approvals and rejections require an admin and the corresponding write scope.

| Scope              | Operations                                                         |
| ------------------ | ------------------------------------------------------------------ |
| `read`             | Business, contracts, timesheets, milestones, payments and balances |
| `contracts:write`  | Initialize a contract draft                                        |
| `timesheets:write` | Approve or reject a submitted timesheet                            |
| `milestones:write` | Approve or reject a submitted milestone                            |

Responses contain a curated public representation. Single resources are bare objects; lists return `{ data, hasMore, nextCursor }`. Money is a decimal string with currency precision. Keep it as a string or use a decimal library. Payroll dates use `YYYY-MM-DD`; timestamps use UTC ISO 8601.

## Create a draft

`POST /v1/contracts` initializes a draft for completion and review in Shor. It accepts title, description, professional email, employment/contract type, country of employment, start/end dates and an optional external reference. It does not sign or activate a contract or accept the dashboard's nested compensation/wizard payload.

Every POST requires `Content-Type: application/json` and `Idempotency-Key`, a unique intent identifier of 16–128 letters, digits, underscores or hyphens. Generate it once, persist it in your integration, and reuse it with exactly the same request for retries. Generate a new identifier for each intentional new action, even when its arguments are identical.

```bash theme={null}
curl "$SHOR_API_URL/v1/contracts" \
  -H "Authorization: Bearer $SHOR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $INTENT_ID" \
  -d '{"title":"Design project","externalReference":"your-system-record-123"}'
```

Successful operation results are retained for seven days. A completed retry returns the original result with `Idempotency-Replayed: true`; current resource state may since have changed. Never reuse an old key after retention. `externalReference` provides durable draft correlation after operation retention and is unique within the workspace and integration principal. Key rotation preserves that principal. An independently created key or a different MCP grant is a different integration.

## Approve work

Fetch the timesheet or milestone, review its amount, currency and payment date, then send its `version` as `expectedVersion` to `/timesheets/{id}/approve` or `/milestones/{id}/approve`. Rejection uses `/reject` and also requires a nonempty `reason`.

A changed review returns `STALE_RESOURCE_VERSION`. Fetch and review again before creating a new intent. Approval creates a payment; it does not mean the worker has been paid. Timesheet processing follows its due date and effective auto-pay setting. Milestone approval attempts payment processing immediately. Follow `paymentId` and poll the payment resource for pending, processing, completed or failed state.

## Errors and retries

Errors return `{ error: { type, code, message, status, requestId, details? } }`. Retain the request ID when contacting support; do not log credentials or sensitive request bodies.

| Status/code                                    | Next step                                                  |
| ---------------------------------------------- | ---------------------------------------------------------- |
| 401 `INVALID_CREDENTIAL`                       | Check credential, expiry and environment                   |
| 403 `INSUFFICIENT_SCOPE`                       | Check grant and current membership role                    |
| 403 `INTEGRATION_DISABLED` / `WRITES_DISABLED` | Contact the workspace administrator or Shor                |
| 409 `STALE_RESOURCE_VERSION`                   | Fetch and review current state before a new intent         |
| 409 `IDEMPOTENCY_KEY_REUSED`                   | Use the original payload or a new intentional operation    |
| 409 `OPERATION_IN_PROGRESS`                    | Retry the same request after a short delay                 |
| 409 `OPERATION_EXPIRED`                        | Reconcile resource state; do not blindly repeat the action |
| 409 `EXTERNAL_REFERENCE_EXISTS`                | Look up the contract using `externalReference`             |
| 429                                            | Honor `Retry-After`                                        |
| 503                                            | Retry with backoff; balance is unavailable, not zero       |

Limits currently allow 600 reads and 60 writes per principal per minute, with a shared workspace ceiling of 2,000 requests per minute. Failed-auth admission has a separate limit. Responses include rate-limit headers. Retry transient network/502/503/504 errors with exponential backoff, preserving the key and payload for writes. Resolve validation, authorization and state conflicts before retrying.
