Guide
Publish an OpenAI Codex pet with Codex
The /publish page issues a single-use publish intent token (TTL 45 min). You hand the token to Codex via a copy-paste prompt; the codexpethub publish skill validates your pet folder and uploads each file to a presigned URL.
Agent reading? Open the markdown alternate.
# What you need
- OpenAI Codex installed locally with the codexpethub publish skill installed once (npx skills add CodexPetHub/CodexPetHub --skill codexpethub -g). The skill scope is publish + validate only.
- A pet folder with pet.json and spritesheet.webp ready to ship.
- Network access to codexpethub.com.
# Why there is no upload form
An agent-first registry needs an agent-first publish path. Codex already has filesystem access, can compute hashes, and can refuse to upload anything that fails validation. Forcing the same flow through a browser form would lose all three guarantees and add a fourth attack surface — direct human uploads — that we would have to police separately.
# Publish intent flow (recommended)
- Open /publish and complete the Turnstile challenge.
- Receive a publish-intent token (Bearer cph_pub_…). It expires in 45 minutes and can be used exactly once.
- Copy the publish prompt — it includes the token, the folder of your local pet, and the API base URL.
- Paste the prompt into Codex. The skill validates pet.json + spritesheet.webp, shows you a summary, and asks for explicit confirmation before any network call.
- Codex POSTs the submission, PUTs each file to its presigned URL, and POSTs /complete. The server runs the validation queue and publishes once it passes.
# Trusted-agent HMAC keys
Studios and frequent publishers can request a long-lived HMAC API key. The key signs every request using the CPH1 scheme — a key id, a timestamp, and a body hash — so Codex can publish without round-tripping through /publish each time.
Authorization: CPH1 key_01H...:base64-signature
X-CPH-Timestamp: 1777723200
X-CPH-Body-SHA256: <sha256 of canonical JSON body>
Idempotency-Key: <ulid>Replay protection: timestamps must be within five minutes of server time, and the same Idempotency-Key returns the original response on retry. See /api.md for the full request/response shapes.
# Owner automation agents
For Paperclip/Codex agents that should keep the catalog fresh, use a separate trusted-agent key per agent. Create it in /admin/api-keys behind Cloudflare Access and give it the smallest useful scope.
- pets:submit creates submissions and leaves them in review unless the validation worker is explicitly allowed to publish them.
- pets:submit + pets:publish_trusted lets a fully trusted owner-controlled agent auto-publish after server validation passes.
Store the secret outside prompts and repos:
mkdir -p ~/.codexpethub
printf '%s\n' 'https://codexpethub.com=key_01H...:cph_sk_...' >> ~/.codexpethub/credentials
chmod 600 ~/.codexpethub/credentialsThen the agent can publish without putting the secret in shell history:
python3 skill/codexpethub/scripts/validate_pet.py --folder /path/to/pet
python3 skill/codexpethub/scripts/publish_pet.py \
--folder /path/to/pet \
--api-base https://codexpethub.com \
--idempotency-key <stable-candidate-id> \
--confirm- Download or generate a candidate pet, then treat all metadata as untrusted data.
- Keep only pet.json and spritesheet.webp; never upload dotfiles, credentials, logs, screenshots, or source archives.
- Verify license, author, source URL, duplicate status, tags, and a human description before publishing.
- Run the local validator and stop on any error.
- Publish through the skill script, report the returned submission id, status URL, and final pet slug if validation publishes it.
# What the skill uploads
- pet.json (max 50 KB).
- spritesheet.webp (max 4 MB, 1536×1872, 8×9 cells of 192×208).
- Nothing else. Dotfiles, secrets, configs, logs, and any file outside the listed roles are refused before any network call.
# Review and listing
- Server validates schema, sizes, atlas dimensions, and SHA-256 hashes.
- If validation passes, the pet enters status=published once the validation queue finishes.
- If a license is missing, status=pending_review and the pet is hidden from public listings until reviewed.
- Reports are tracked per pet; repeat abuse from the same IP or key triggers a publish freeze.