papi Plugin
Make authenticated calls to the Personio Public API (papi) from Claude Code. This plugin owns the boring-but-critical parts — credential storage, token exchange, caching, and dev/prod environment selection — so you can focus on composing the actual request.
Installation
/plugin install papi@personio-claude-code-marketplace
What does this plugin do?
papi Skill
Claude will use this skill whenever you mention the Personio Public API, papi, or a /v2/... endpoint. It handles:
- One-time credential setup — stores
client_id/client_secretin the macOS keychain (never in chat, never on disk in plaintext). - Token exchange and caching — hits
POST /v2/auth/tokenand caches the bearer under~/.cache/personio-papi/for ~23h, reusing it across turns and sessions. - Environment switching — remembers whether you were last using dev or prod, so
curlcommands land on the right host. - Safety rails — prompts for confirmation before prod writes and destructive operations; refuses to print secrets or tokens.
This skill deliberately does not hardcode endpoint paths. For endpoint specifics, Claude will defer to the Personio Developer Hub or a domain-specific sibling skill (e.g. one focused on attendance or employees).
What you need
- macOS (the skill uses the macOS
securitycommand for keychain access) curlandjq- A Personio Public API credential pair (
client_id+client_secret) — see first-time setup below
First-time setup
The skill walks you through this on first invocation, but the gist is:
- Log in to your Personio tenant as an admin.
- Go to Settings → Integrations → API credentials (the path varies slightly by tenant version — look for "API credentials" or "Custom integrations").
- Create a new custom integration / credential pair. Grant the scopes you'll need (e.g.
personio:attendances:read,personio:employees:write). - Copy the
client_idandclient_secret— the secret is shown only once. - Paste them into Claude when prompted; they go into the macOS keychain under service
personio-papi-devorpersonio-papi-prod.
Reference: https://developer.personio.de/docs/getting-started-with-the-personio-api
Example usage
You: "Use the Personio public API to look up the employee with id 397092 on the dev tenant."
Claude:
- Checks keychain for
personio-papi-devcredentials. - Runs
scripts/get_token.sh devto fetch a cached or fresh bearer token. - Resolves host via
scripts/host.sh dev→https://api.dev.personio-internal.de. - Composes and runs:
curl -sS "$HOST/v2/employees/397092" \ -H "Authorization: Bearer $TOKEN" - Summarizes the response (name, email, employment status) without pasting the full JSON blob.
Hosts
| Env | Host |
|---|---|
| dev | https://api.dev.personio-internal.de |
| prod | https://api.personio.de |
State locations
| What | Where |
|---|---|
| Client id / secret | macOS keychain, service personio-papi-<env> |
| Last-used environment | ~/.config/papi/config.json |
| Cached bearer token | ${XDG_CACHE_HOME:-~/.cache}/personio-papi/token-<env> (dir 700, file 600, ~23h lifetime) |
Safety
- Secrets and tokens are never printed to chat.
- Prod writes require explicit user confirmation.
- Destructive operations (
DELETE, bulkPATCH) list affected resources and ask before proceeding. - Credentials never leave the keychain; tokens never leave the per-user cache dir and the current process.