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

# Securing your integration

> What to do on your side of the credential — keys, scope, data handling, audit trail and incident response

[Security & data handling](/security) covers what PracticeHub does — tenancy, credential storage, transport, logging, change management. This page is the other half: what **you** should do with the credential once we've issued it. Nothing here is optional advice dressed up as a platform guarantee — where a mechanism is ours (rotation, scoping, attribution, audit logging), it's linked to where that's documented; where it's a practice you need to follow, it's stated as one.

## Keys

* **Server-side only.** A key is a bearer credential for your account's data — never ship one in a browser, a mobile app binary, or a public repository. Keep it in an environment variable or a secrets manager, the same as any other database credential or third-party API key.
* **One key per integration, named for what it is.** "Booking widget" and "nightly export" should be two keys, not one shared secret. Requests and audit trails are per key (the rate limit is shared across the account), so a name that describes the integration makes revocation surgical — you can cut off one integration without touching another — and it's the name that shows up in the account's own audit trail (every record you write is attributed to your key by name, for example an appointment log reading *"Created via API: Booking widget"* — see [Auditability](#auditability)).
* **Rotate on a schedule using the built-in flow**, not by re-pasting a key that's been sitting in a `.env` file for a year. From **Developers → API Keys → ⋯ → Rotate**, the integration gets a new secret while the previous one keeps working for a **24-hour grace period** — long enough to redeploy without downtime, short enough that the old secret isn't live indefinitely. See [Rotation, expiry and audit](/authentication#rotation-expiry-and-audit).
* **Revoke — don't just rotate — the moment you suspect a key has actually leaked.** Rotation is for planned handover and deliberately keeps the old secret alive for 24 hours; revocation is immediate and is the right tool once you think a secret is out. Revoke from the same **Developers → API Keys** page.
* **Set an expiry that matches the integration's lifetime.** A key can be created with no expiry, or set to expire in 90 days or 1 year; a short-lived project (a migration, a one-off export) should get a short expiry rather than a key that outlives the project.

## Least privilege

* **Read-only until you need to write.** A read-only key is refused on every write path — enforced once centrally rather than per endpoint — so it's the cheapest control available: reporting, sync and dashboard integrations that never create or change data should use one. See [API keys](/authentication#api-keys).
* **Scope is per key, not per account.** If one integration needs to write and another only needs to read, give them separate keys with separate scopes rather than a shared read & write key.
* **A connector is the team member, not a separate service account.** An OAuth connector (Claude or ChatGPT) acts as the PracticeHub role of the person who approved it — it can do exactly what they could do by hand, including their own-patients / own-calendar ringfencing if their role is restricted that way. It is not a way to get broader access than an API key, and it's not the right credential for something automated and unattended — that's what a key is for. See [Administering AI connectors](/mcp/administration).
* **Turn on *Connect AI apps* deliberately, per role.** Connecting an assistant is opt-in: account owners and super users can always do it, everyone else needs the *Connect AI apps (Claude, ChatGPT)* toggle on their role under **Settings → Security → Roles**. Only enable it for roles that should be able to book, edit or move things through an assistant — a read-only front-desk role may not need it at all.

## Data handling

* **You're pulling health-adjacent data — keep only what the integration needs.** Store the PracticeHub id and re-fetch details when you need them rather than mirroring full patient records; the less of it you hold, the less you have to protect and the less can go stale.
* **Honour deletions.** A deleted or voided record stops being served and appears in `deleted_entities` (read-only, `writes → 405`) so a syncing integration can detect the removal instead of continuing to hold a copy — see [What each resource accepts](/guides/writing#what-each-resource-accepts). A `404` on something you previously fetched means the same thing: remove or archive it on your side.
* **Don't log response bodies on your end.** Responses can contain patient data; if you log API calls for debugging, log the `X-Request-Id` and status, not the payload. This mirrors how PracticeHub's own request logging works — see [Logging and what is stored about your calls](/security#logging-and-what-is-stored-about-your-calls).
* **TLS is mandatory, not optional.** The API and MCP server only accept HTTPS; if you run a webhook receiver or any endpoint that PracticeHub or your own systems call back into, it needs to be HTTPS too.

## Auditability

* **Every write you make is attributed to your key.** Records changed through the API carry the integration's name in their own history (*"Created via API: Booking widget"*), and connector actions carry the team member's name instead. There's no anonymous write — a meaningful key name is what makes that trail useful to the practice later.
* **The practice can see your calls.** **Developers → API Logs** is a filterable report of every request your key or a connector has made — method, path, resource, status, latency, request id — so don't treat your integration as invisible; assume a practice admin can and will look.
* **Connector approvals and revocations are their own audit events**, separate from the per-call log: `connector_authorised`, `connector_revoked`, and the key equivalents `api_key_created`, `api_key_rotated`, `api_key_revoked` are all written to the account's security activity log (**Reports → User Activity**, filtered to "security"). See [What's audit-logged](/mcp/administration#what-s-audit-logged).

## Incident response

If you believe a key has leaked or a connector has been misused:

<Steps>
  <Step title="Revoke the credential immediately">
    From **Developers → API Keys**, revoke the key outright (not rotate — revocation cuts access off immediately, where rotation intentionally keeps the old secret alive for 24 hours). For a connector, revoke it from **Connected AI apps**; that also revokes its refresh token, so the AI app can't silently mint a new access token.
  </Step>

  <Step title="Issue a fresh credential">
    Create a new key (or have the team member reconnect the AI app) to resume the integration once you've addressed how the original one leaked.
  </Step>

  <Step title="Check API Logs for the affected window">
    **Developers → API Logs** shows exactly what the credential did before you revoked it — method, path, resource, timestamps — so you can tell what, if anything, needs to be corrected or disclosed.
  </Step>

  <Step title="Contact PracticeHub with trace ids">
    Every response carries an `X-Request-Id`; if you have logs of specific calls you're concerned about, send those ids to [help@practicehub.io](mailto:help@practicehub.io) so we can trace them on our side too.
  </Step>
</Steps>

<Note>
  This page describes what to do with your own credentials. For what PracticeHub itself guarantees — tenancy isolation, credential storage, transport, request logging, and webhook signing — see [Security & data handling](/security).
</Note>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.