• Home
  • FAQ
  • Features
  • Docs
  • About
  • Pricing
Log In
Log InJoin Now

Get Pet Data

Retrieve public pet data safely and efficiently

Use the PawPlacer public API to fetch lightweight pet data for embeds, websites, and partner integrations. All endpoints require an API key sent in the x-api-key header and return only pets marked as public.

Endpoint Summary

EndpointPurposeRate Limit
GET /api/petsPaginated list of public pets100 requests/hour
GET /api/pets?…Filtered slice using query parameters100 requests/hour
GET /api/pets/{petId}Single public pet400 requests/hour
GET /api/pets/custom-fieldsCustom field metadata for pet forms15 requests/hour

Cache responses for at least a few minutes to stay well below the hourly limits. The payloads are designed to be CDN-cacheable and stable.

OpenAPI 3.1 contract: https://pawplacer.com/openapi/public-api-v1.yaml

Standard Response Headers

All public pet endpoints now include diagnostic and rate-limit headers:

  • X-Request-Id — unique request identifier for support/debugging
  • X-Api-Version — current public API contract version
  • X-Generated-At — response generation timestamp (ISO-8601)
  • X-RateLimit-Limit — endpoint hourly limit
  • X-RateLimit-Remaining — remaining calls in current window (-1 when unavailable)
  • X-RateLimit-Reset — Unix timestamp for next limit reset window
  • Retry-After — present on 429 responses

GET /api/pets – List Public Pets

Returns a paginated list of public pets with a full pet profile payload (including custom fields and metadata).

Request

GET https://pawplacer.com/api/pets
x-api-key: YOUR_API_KEY

Optional query parameters

  • limit — 1–100 (default 20)
  • offset — results to skip (default 0)
  • species — dog, cat, or rabbit
  • status — matches your custom status labels (case-insensitive)
  • search — fuzzy match on name, description, and breed values
  • updated_since — ISO-8601 timestamp; returns only pets with updated_at >= updated_since

JavaScript example

const response = await fetch('https://pawplacer.com/api/pets?status=available&species=dog&limit=12', {
  headers: { 'x-api-key': process.env.PAWPLACER_API_KEY }
});

const { pets, total, hasMore } = await response.json();

Response

{
  "pets": [
    {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "name": "Max",
      "species": "dog",
      "status": "Available",
      "health": "good",
      "show_public": true,
      "breed": ["Labrador Retriever"],
      "color": ["Black"],
      "age_category": "young",
      "age_years": null,
      "age_months": null,
      "age_birthday": null,
      "sex": "male",
      "size": "medium",
      "description": "Friendly and energetic dog",
      "spayed": true,
      "adoption_fee": "250",
      "microchip_id": null,
      "good_with": ["families", "kids"],
      "bad_with": [],
      "temperaments": ["playful", "social"],
      "image_urls": [
        "https://pawplacer.com/pets/max.jpg",
        "https://pawplacer.com/pets/max-2.jpg"
      ],
      "image_url": "https://pawplacer.com/pets/max.jpg",
      "coat_length": "short",
      "custom_id": "EXT-1001",
      "custom_field_data": {
        "favorite_toy": "Tennis ball"
      },
      "intake_date": null,
      "outcome_date": null,
      "primary_veterinarian": "Downtown Vet Clinic",
      "special_needs": [],
      "tags": ["Senior", "Special Care"],
      "status_change_notes": null,
      "weight": null,
      "adopted_on": null,
      "adopted_by": "Jane Foster",
      "created_at": "2026-02-17T12:00:00.000000+00:00",
      "updated_at": "2026-02-17T12:00:00.000000+00:00"
    }
  ],
  "total": 42,
  "limit": 12,
  "offset": 0,
  "hasMore": true
}

Fields returned

  • pets — array of public pets. Each object includes a full profile payload:
    • Core: id, name, species, status, health, show_public
    • Demographics: breed, color, age_category, age_years, age_months, age_birthday, sex, size, weight, spayed
    • Behavior/compatibility: good_with, bad_with, temperaments, special_needs
    • Tags: tags (pet tag labels)
    • Identifiers: custom_id, microchip_id
    • Notes + dates: description, intake_date, outcome_date, status_change_notes
    • Relationships (resolved names): primary_veterinarian, adopted_by
    • Media: image_urls, image_url, coat_length
    • Custom data: custom_field_data
    • Metadata: created_at, updated_at, adopted_on
  • total, limit, offset, hasMore — pagination metadata

GET /api/pets/{petId} – Single Pet

Fetch a single public pet by ID. This endpoint returns the same field set as the list endpoint.

Request

GET https://pawplacer.com/api/pets/{petId}
x-api-key: YOUR_API_KEY

JavaScript example

const response = await fetch(`https://pawplacer.com/api/pets/${petId}`, {
  headers: { 'x-api-key': process.env.PAWPLACER_API_KEY }
});

const pet = await response.json();

If the pet is not public, deleted, or does not exist, the API responds with 404 and { "error": "Pet not found" }.

GET /api/pets/custom-fields – Custom Field Metadata

Retrieve configured custom form fields so you can send valid keys when creating pets.

Request

GET https://pawplacer.com/api/pets/custom-fields
x-api-key: YOUR_API_KEY

Response

{
  "custom_fields": [
    {
      "field_key": "favorite_toy",
      "label": "Favorite Toy",
      "field_type": "text",
      "required": false,
      "help_text": "Include any comfort objects",
      "options": null,
      "section": "Behavior"
    }
  ]
}

Use the field_key (not the label) when populating custom_field_data in POST /api/pets requests.

Rate Limit Errors

Rate limits are enforced per organization on a rolling hourly window. If the limit is exceeded, the response is 429 with a descriptive error payload, for example:

{
  "error": "Rate limit exceeded. Maximum 100 requests per hour. Cache responses to avoid throttling.",
  "code": "rate_limited",
  "request_id": "3dfabc8f-3f6f-4f4e-bffe-5d0dc5292e6f"
}

Reduce the frequency of calls or increase your cache window before retrying.

Error Reference

StatusReasonExample Payload
401Missing or invalid API key{ "error": "API key required", "code": "api_key_required", "request_id": "..." }
404Pet not found{ "error": "Pet not found", "code": "pet_not_found", "request_id": "..." }
429Rate limit exceededsee example above
500Unexpected server issue{ "error": "Something went wrong", "code": "internal_error", "request_id": "..." }

Always handle non-200 status codes and back off when you see 429 responses.

PreviousManaging Foster StatusNextAdd New Pets

PawPlacer

© Copyright 2026 PawPlacer. All Rights Reserved.

Contact
  • Email
About
  • About Us
  • Funding Philosophy
  • Careers
  • FAQ
  • Pricing
  • Changelog
Legal
  • Terms of Service
  • Privacy Policy
  • Cookie Policy