The PawPlacer public API gives you read and write access to pets, adopters, fosters, adoption fees, and contracts so you can power listings, embeds, forms, and partner workflows. Every request requires an API key created in Settings → API and must be issued from a trusted server-side environment.
Pick your integration path
- Use the official JavaScript SDK for typed helpers, caching, and retries.
- Synchronize adoptable pets to your website or mobile app directly via the public API.
- Embed filtered lists (featured pets, species-specific pages, adoption campaigns).
- Create new pet profiles from intake kiosks or partner systems.
- Populate forms with the same custom fields your staff uses internally.
- Run incremental sync jobs using
GET /api/pets?updated_since=.... - Create adopter or foster records from external application forms.
- Display adoption fee schedules and terms & conditions on your own website.
Available Endpoints
Pets
| Endpoint | Description | Rate Limit |
|---|---|---|
GET /api/pets | Paginated list of public pets with filtering | 100/hr |
GET /api/pets/{petId} | Fetch a single public pet | 400/hr |
GET /api/pets/custom-fields | Custom form field metadata for pets | 15/hr |
POST /api/pets | Create a new pet record | 10/hr |
People (Adopters & Fosters)
| Endpoint | Description | Rate Limit |
|---|---|---|
GET /api/people?type=adopter|foster | Paginated list of adopters or fosters | 100/hr |
GET /api/people/{id}?type=adopter|foster | Fetch a single adopter or foster | 400/hr |
GET /api/people/custom-fields?type=adopter|foster | Custom form field metadata | 15/hr |
POST /api/people | Create an adopter or foster | 10/hr |
Adoption Fees & Contracts
| Endpoint | Description | Rate Limit |
|---|---|---|
GET /api/adoption-fees | Fee configuration rules (species + attribute + adjustment) | 15/hr |
GET /api/contracts?type=adopter|foster|volunteer|surrender | Terms & conditions content (markdown) | 15/hr |
All endpoints respond with JSON. CORS is enabled so you can proxy requests through your own backend, but never expose your API key to untrusted clients.
Standard API Metadata
Every public endpoint includes:
X-Request-Idfor tracing support issuesX-Api-VersionandX-Generated-Atfor contract/timing visibilityX-RateLimit-*headers to expose current limit window state
OpenAPI 3.1 Contract
Use the official OpenAPI contract for language-agnostic integrations, Postman imports, and client generation:
- Spec URL:
https://pawplacer.com/openapi/public-api-v1.yaml
Authentication
PawPlacer supports scoped API keys:
readkeys can call all GET endpoints (pets, people, adoption fees, contracts, custom fields)writekeys can call POST endpoints (POST /api/pets,POST /api/people) plus all read endpoints
Send your API key in the x-api-key header:
const response = await fetch('https://pawplacer.com/api/pets', {
headers: { 'x-api-key': process.env.PAWPLACER_API_KEY }
});
Missing keys return 401 with { "error": "API key required", "code": "api_key_required", "request_id": "..." }, and invalid keys return 401 with { "error": "Invalid API key", "code": "invalid_api_key", "request_id": "..." }.
Handling Rate Limits
The API enforces rate limits per API key and endpoint. When a limit is hit you receive 429 and a descriptive JSON error. Best practices:
- Cache responses for at least 5–10 minutes.
- Batch frontend requests through your server.
- Use background jobs to refresh data instead of polling from client devices.
Quick Start Workflow
- Generate an API key in Settings → API.
- Call
GET /api/petswith the key to render public listings. - Call
GET /api/people?type=adopterto fetch your adopter records. - Fetch
GET /api/pets/custom-fieldsorGET /api/people/custom-fields?type=adopterto learn validfield_keyvalues. - Create records via
POST /api/petsorPOST /api/peoplewhen you need to push data into PawPlacer. - Fetch
GET /api/adoption-feesandGET /api/contracts?type=adopterto display fee schedules and agreements.
Example Requests
const headers = { 'x-api-key': process.env.PAWPLACER_API_KEY };
// List adoptable dogs
const dogs = await fetch('https://pawplacer.com/api/pets?species=dog&status=available&limit=8', { headers }).then(r => r.json());
// Fetch a single pet
const pet = await fetch(`https://pawplacer.com/api/pets/${dogs.pets[0].id}`, { headers }).then(r => r.json());
// List active adopters
const adopters = await fetch('https://pawplacer.com/api/people?type=adopter&status=active', { headers }).then(r => r.json());
// Create an adopter
const newAdopter = await fetch('https://pawplacer.com/api/people', {
method: 'POST',
headers: { ...headers, 'Content-Type': 'application/json' },
body: JSON.stringify({ type: 'adopter', name: 'Jane Smith', email: 'jane@example.com' })
}).then(r => r.json());
// Fetch adoption fee rules
const fees = await fetch('https://pawplacer.com/api/adoption-fees', { headers }).then(r => r.json());
// Fetch adoption contract (markdown)
const contract = await fetch('https://pawplacer.com/api/contracts?type=adopter', { headers }).then(r => r.json());
Security Checklist
- Keep API keys in environment variables or secret managers.
- Proxy requests through your own backend when serving public sites.
- Rotate keys immediately if you suspect they were exposed.
- Respect rate limits and handle error responses gracefully.
Next Steps
- Follow the detailed GET guide for response formats and error handling.
- Review the POST guide to understand required fields and validation for pet and people creation.
- Visit Settings → API to create, rotate, or revoke scoped keys for each integration.