---
title: API keys and connected apps
slug: api-keys
description: How to create, store, expire and revoke Personizely API keys, who can manage them, and how to review and disconnect OAuth apps like Claude, ChatGPT or Zapier.
docTags: 
createdAt: 2026-10-16T19:50:09.795Z
---

API keys and connected apps are the two ways to give code access to your Personizely account through the [REST API](docId\:HG88NTwtq60d17m6jFErF) and the [MCP server](docId\:usaccUEvfdBFWxe_Z1uuN). An API key is a secret you create and paste into your own script or tool. A connected app is a third-party tool, such as Claude, ChatGPT or Zapier, that you authorize by signing in with OAuth. You manage both under **Account → API**.

**Who can manage them:** account owners and admins.

## How it works

- **Access is per account.** A key or connected app can reach every website in the account. API calls pick a website with the `websiteId` parameter.
- **API keys have full access.** Every key can read data and start or stop campaigns and widgets. There's no read-only key.
- **Connected apps have the access you approved.** When you authorize an app, the consent screen lists what it asks for: `read` (view campaigns, widgets, goals, targets and results) and, if requested, `write` (start and stop campaigns and widgets).
- **Keys belong to the person who created them.** The key list shows each key's name, the start of the key, when it was created, when it was last used and when it expires.

## Create an API key

1. Go to **Account → API**.
2. Create a new key and give it a name that says where it's used, such as "Looker sync" or "CI release pipeline". Names can be up to 100 characters.
3. Optionally set an expiry date. After that date, requests with the key fail with `401 API key has expired`.
4. Copy the key. It starts with `ply_live_` and is **shown only once**. Personizely stores only a hash, so a lost key can't be recovered. Create a new one instead.

Use the key as a bearer token:

```bash
curl https://api.personizely.net/v1/websites \
  -H "Authorization: Bearer ply_live_XXXXXXXXXXXXXXXX"
```

| Option      | What it does                           | Values / default               |
| ----------- | -------------------------------------- | ------------------------------ |
| Name        | Label shown in the key list            | Required, up to 100 characters |
| Expiry date | Date after which the key stops working | Optional; no expiry by default |

## Revoke an API key

Revoke a key from the list under **Account → API**. Revoking takes effect immediately: the next request with that key fails with `401 API key has been revoked`. Revoking can't be undone.

## Connected apps (OAuth)

Apps that connect with OAuth, such as AI assistants using the [MCP server](docId\:usaccUEvfdBFWxe_Z1uuN), appear under **Account → API** once you've authorized them.

**To connect an app:** start the connection in the app. You're sent to Personizely, where you sign in, choose which account to connect if you belong to several, and approve. You must be an owner or admin of that account.

**To disconnect an app:** remove it from the list under **Account → API**. This revokes its access, and the app has to be authorized again before it can make requests.

Building an app yourself? See [OAuth 2.1 in the REST API overview](docId\:HG88NTwtq60d17m6jFErF#oauth-21).

## Behavior details and limitations

- **No scoped keys.** Every API key can start and stop campaigns and widgets. If a tool should only read data, connect it with OAuth and approve `read` only.
- **No per-website keys.** A key works for every website in the account. If you need to isolate a client's data, use a separate account; agencies can use [Agencies, white label and subaccounts](docId:0Z99JhxKBbKGUMVzC3lfp).
- **"Last used" updates on every successful request.** Use it to find keys that are no longer used, and revoke them.
- **Offboarding.** When someone leaves the team, revoke the keys they created.
- **The storefront doesn't need a key.** The snippet and the [JavaScript API (window.ply)](docId\:d64TegyOiwNA2GFG1eXPm) work without one. Never put an API key in theme code, a tag manager or any page a visitor can load.

## Good practice

- Create one key per integration, so you can revoke one without breaking the others.
- Store keys in a secret manager or CI secret, not in source code.
- Set an expiry date on keys for one-off jobs or contractors.
- If a key may have leaked, revoke it first, then create a replacement.

## Troubleshooting

- **`401 Invalid API key`** → the key was copied incompletely, has extra whitespace, or the `Bearer ` prefix is missing from the header.
- **`401 API key has expired`** → the expiry date has passed. Create a new key.
- **`401 API key has been revoked`** → someone revoked it under **Account → API**. Create a new key.
- **`403` when starting or stopping** → you're using an OAuth app that only has `read` access. Reconnect it and approve `write`, or use an API key.
- **Can't create keys or authorize apps** → you have the User role. Ask an owner or admin.

## Related

- [REST API](docId\:HG88NTwtq60d17m6jFErF)
- [MCP server](docId\:usaccUEvfdBFWxe_Z1uuN)
- [Account, team and roles](docId\:H2B5mIcnjYpbOOCXOgUwm)
- [Agencies, white label and subaccounts](docId:0Z99JhxKBbKGUMVzC3lfp)
