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

# Frequently asked questions

> Answers to common questions about credentials, environments, scope, requests, resources, retries, and operations.

## Access and API keys

<AccordionGroup>
  <Accordion title="How do I create an API key?" defaultOpen>
    Open [JobHandy Administration](https://app.jobhandy.io/admin), go to **IT Settings**, select **API Keys**, and click **Create API Key**. See [API Key Management](/get-started/api-key-management).
  </Accordion>

  <Accordion title="Which portal permissions can manage keys?">
    At least one of **IT**, **HR**, or **Company-Admin** is required.
  </Accordion>

  <Accordion title="Can I create multiple keys?">
    Yes. Use separate keys for separate integrations, responsibilities, or scopes.
  </Accordion>

  <Accordion title="Can one key access multiple companies?">
    A key can be scoped to the companies and divisions selected in the administration portal. The API then represents each authorized company as a tenant context.
  </Accordion>

  <Accordion title="Can I change an existing key name or scope?">
    The documented operational approach does not rely on in-place credential changes. Create a replacement key with the required name and scope, deploy and verify it, then deactivate the old key.
  </Accordion>

  <Accordion title="Can I see the complete key again?">
    Treat the creation display as the secure capture point. If the credential is unavailable, create and deploy a replacement rather than relying on recovery of a secret value.
  </Accordion>

  <Accordion title="What is the difference between deactivation and deletion?">
    Deactivation stops authentication and allows later reactivation. Deletion permanently retires the key from the portal workflow.
  </Accordion>
</AccordionGroup>

## Environments and testing

<AccordionGroup>
  <Accordion title="Is there a public sandbox or stage base URL?" defaultOpen>
    The public contract documents only `https://api.jobhandy.io/v1`. Internal development hosts are not part of customer configuration.
  </Accordion>

  <Accordion title="Is dryRun=true a test environment?">
    No. It validates a supported write against current production scope and state without applying the documented mutation or side effects.
  </Accordion>

  <Accordion title="Does dry run guarantee the real write will succeed?">
    No. It does not lock or reserve state. Revalidate conflicts on the real request.
  </Accordion>
</AccordionGroup>

## Tenant and scope

<AccordionGroup>
  <Accordion title="What is the difference between Company and Tenant?" defaultOpen>
    Company is the business-facing portal term. Tenant is the technical API boundary and identifier for that organization.
  </Accordion>

  <Accordion title="When is X-Tenant-ID required?">
    Send it when an operation cannot otherwise resolve one tenant or when you intentionally want to restrict a collection to one authorized tenant.
  </Accordion>

  <Accordion title="Can X-Tenant-ID grant additional access?">
    No. It can only narrow the scope already assigned to the API key.
  </Accordion>

  <Accordion title="How do I obtain a tenant ID?">
    Use the tenant identifier returned in authorized resource representations or the identifier supplied during integration setup. Do not use a company name or division ID.
  </Accordion>

  <Accordion title="Can I move an existing employee to another tenant?">
    Not through `PATCH /employees/{id}`. The endpoint can change or clear `divisionId` only within the same tenant.
  </Accordion>
</AccordionGroup>

## Requests and retries

<AccordionGroup>
  <Accordion title="Is X-Request-ID required?" defaultOpen>
    It is optional but strongly recommended. The API generates one when omitted.
  </Accordion>

  <Accordion title="Is X-Request-ID an idempotency key?">
    No. It is correlation metadata and does not deduplicate a request.
  </Accordion>

  <Accordion title="What should I do after a write timeout?">
    Re-read or search the affected resource before another write. The server might have committed the mutation before the connection timed out.
  </Accordion>

  <Accordion title="Are unknown request fields ignored?">
    No. Request schemas are closed and unknown properties are rejected.
  </Accordion>

  <Accordion title="Can I retry GET requests?">
    Transient read failures are generally safe to retry with bounded backoff. Respect `Retry-After` on `429`.
  </Accordion>
</AccordionGroup>

## Collections and filters

<AccordionGroup>
  <Accordion title="What is the maximum page size?" defaultOpen>
    `pageSize` accepts values from `1` through `1000`; the server default is `100`.
  </Accordion>

  <Accordion title="Can I sort by multiple fields?">
    No. Use exactly one endpoint-supported scalar field, optionally prefixed with `-` for descending order.
  </Accordion>

  <Accordion title="Are string filters case-sensitive?">
    String comparison is case-insensitive. Enum values remain case-sensitive.
  </Accordion>

  <Accordion title="How do I filter names with spaces or apostrophes?">
    Quote values with whitespace and escape an apostrophe with `\'`. URL-encode the complete filter value.
  </Accordion>

  <Accordion title="Are collection pages a snapshot?">
    Snapshot consistency is not guaranteed by the public contract. Use checkpoints and account for concurrent changes.
  </Accordion>
</AccordionGroup>

## Resources

<AccordionGroup>
  <Accordion title="Can I delete an employee?" defaultOpen>
    No public employee delete operation is defined. Use the documented `blocked` state for account blocking and handle deletion through the applicable business process.
  </Accordion>

  <Accordion title="Can I change an employee's work email?">
    Work email is not editable through the public employee patch endpoint.
  </Accordion>

  <Accordion title="Can an order decision be changed?">
    The decision operation is for an order in `under_review`. A final decision can return `ORDER_ALREADY_DECIDED`; re-read and reconcile rather than attempting to overwrite it.
  </Accordion>

  <Accordion title="Can I create an incident for an employee who is not activated?">
    No. `POST /incidents` returns `422 EMPLOYEE_NOT_ACTIVATED` and does not create the incident. Complete the employee activation first, then send a new request with a new `X-Request-ID`.
  </Accordion>

  <Accordion title="When can incident attachments be uploaded?">
    The endpoint accepts image or PDF attachments for an editable completed incident, subject to file-count and complete-body limits.
  </Accordion>

  <Accordion title="Why can a payroll export have fileName = null?">
    The metadata schema explicitly allows `null` when no file was produced. Do not call the download operation blindly.
  </Accordion>
</AccordionGroup>

## Operations

<AccordionGroup>
  <Accordion title="What are the numeric rate limits?" defaultOpen>
    The contract defines `RateLimit-Policy`, `RateLimit`, and `Retry-After` headers rather than one global fixed quota. Read the effective values from responses.
  </Accordion>

  <Accordion title="Does the API provide webhooks?">
    The current public v1 contract does not define webhook registration or event-subscription endpoints. Use client-initiated polling.
  </Accordion>

  <Accordion title="Are official SDKs available?">
    The OpenAPI specification is the authoritative machine-readable contract. Generate or build a client using the tooling appropriate to your environment and add your own operational controls.
  </Accordion>

  <Accordion title="What information is needed for support?">
    Provide UTC time, method, path, status, error code, request ID, tenant context, and sanitized reproduction steps. Never provide the API key.
  </Accordion>
</AccordionGroup>
