animalchecklist-com Recognition API

Photo suggestions for signed-in accounts.

Operations 3

POST /recognitions Identify an animal in a photo #
GET /recognitions/{id} Read your photo suggestion #
POST /recognitions/{id}/confirm Confirm one species suggestion #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/animalchecklist-com:animalchecklist-com-recognition-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

animalchecklist-com-recognition-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Animal Checklist Recognition API
  version: 1.0.0
  summary: Animal catalogue and account features.
  description: 'Search animals in eight languages and read licensed photos and summaries. Public catalogue reads need no account. Photo recognition and account data require a session. Sightings accept an anonymous sync code or an account session. Accounts use email magic links and passkeys. Versioning: URL path `/api/v1`; a breaking change ships as `/api/v2` and `/api/v1` then answers with Deprecation (RFC 9745) and Sunset (RFC 8594) headers for at least 180 days. Pagination: page and per query parameters, with total, page and per repeated in the answer. Batch: `GET /animals?ids=` reads up to 500 animals in one request. Errors: `{"error":{"code","message"}}`. Check each photo licence and source; summaries are Wikipedia CC BY-SA 4.0; names and counts come from iNaturalist and Wikidata.'
  termsOfService: https://animalchecklist.com/about
  contact:
    name: Animal Checklist
    url: https://animalchecklist.com/for-agents
    email: animalchecklist@arnekellmann.de
  license:
    name: CC BY-SA 4.0 (API description only)
    url: https://creativecommons.org/licenses/by-sa/4.0/
servers:
- url: https://animalchecklist.com/api/v1
  description: Production
security: []
tags:
- name: Recognition
  description: Photo suggestions for signed-in accounts.
paths:
  /recognitions:
    post:
      operationId: createRecognition
      summary: Identify an animal in a photo
      description: Upload a JPEG without photo metadata from this site. The result is a suggestion. Each signed-in account can start 20 jobs per day, subject to IP and shared limits.
      tags:
      - Recognition
      security:
      - sessionCookie: []
      parameters:
      - name: X-Account-Id
        in: header
        required: true
        schema:
          type: string
          format: uuid
        description: Account id shown by GET /account. Prevents a browser session change from changing a different account.
      - name: lang
        in: query
        required: false
        schema:
          type: string
          enum:
          - en
          - de
          - es
          - fr
          - it
          - nl
          - pt
          - pl
          default: en
          description: Display language of `name`, category labels and the summary. Falls back to `en`.
        description: Display language. Default `en`.
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
              - image
              properties:
                image:
                  type: string
                  format: binary
                  description: JPEG, at most 4 MiB and 1536 pixels per side.
                previousJobId:
                  type: string
                  format: uuid
                  description: Matched job from this account and the same image. Its species cannot return again.
      responses:
        '202':
          description: Recognition started. Poll the returned job id.
          content:
            application/json:
              schema:
                type: object
                required:
                - data
                properties:
                  data:
                    type: object
                    required:
                    - id
                    - status
                    properties:
                      id:
                        type: string
                        format: uuid
                      status:
                        type: string
                        const: pending
        '400':
          description: Invalid input.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: INVALID_INPUT
                  message: 'page: Number must be at least 1'
        '401':
          description: Sign-in required.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: AUTH_REQUIRED
                  message: Sign in to your account
        '403':
          description: A same-origin request is required.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: INVALID_ORIGIN
                  message: Use this site
        '404':
          description: Not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: NOT_FOUND
                  message: Unknown animal
        '409':
          description: Account changed in another tab.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: ACCOUNT_SWITCH_REQUIRED
                  message: Refresh your account before changing data
        '413':
          description: Image too large.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: TOO_LARGE
                  message: Image is too large
        '429':
          description: Rate limited.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: RATE_LIMITED
                  message: Too many requests; try again later
          headers:
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait.
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimit-Policy'
        '500':
          description: Unexpected error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: INTERNAL
                  message: Unexpected error
        '503':
          description: Recognition unavailable.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: RECOGNITION_UNAVAILABLE
                  message: Recognition is unavailable
  /recognitions/{id}:
    get:
      operationId: getRecognition
      summary: Read your photo suggestion
      description: Returns the current status of a recognition job owned by this account. Jobs can include up to three species choices. Missing species require explicit confirmation before catalog import. Quality, accepted taxonomy, licensed photos, and specialist agreement govern import eligibility. A family alone cannot be confirmed. Jobs expire after 24 hours.
      tags:
      - Recognition
      security:
      - sessionCookie: []
      parameters:
      - name: X-Account-Id
        in: header
        required: true
        schema:
          type: string
          format: uuid
        description: Account id shown by GET /account. Prevents a browser session change from changing a different account.
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: Job id returned by POST /recognitions.
      - name: lang
        in: query
        required: false
        schema:
          type: string
          enum:
          - en
          - de
          - es
          - fr
          - it
          - nl
          - pt
          - pl
          default: en
          description: Display language of `name`, category labels and the summary. Falls back to `en`.
        description: Display language. Default `en`.
      responses:
        '200':
          description: Current job status. Private and not cached.
          headers:
            Deprecation:
              $ref: '#/components/headers/Deprecation'
            Sunset:
              $ref: '#/components/headers/Sunset'
          content:
            application/json:
              schema:
                type: object
                required:
                - data
                properties:
                  data:
                    type: object
                    required:
                    - id
                    - status
                    - excludedIds
                    properties:
                      id:
                        type: string
                        format: uuid
                      status:
                        type: string
                        enum:
                        - pending
                        - matched
                        - no_match
                        - failed
                      animal:
                        $ref: '#/components/schemas/AnimalSummary'
                      family:
                        type: object
                        required:
                        - rank
                        - nameSci
                        properties:
                          rank:
                            type: string
                            enum:
                            - family
                          nameSci:
                            type: string
                            description: Animal family name validated against the GBIF Backbone Taxonomy.
                            example: Theraphosidae
                      uncertainty:
                        type: string
                        enum:
                        - low_quality
                        - specialist_disagrees
                        description: Low detail prevents a definite family result.
                      candidates:
                        type: array
                        maxItems: 3
                        items:
                          type: object
                          required:
                          - id
                          - nameSci
                          - nameEn
                          - nameDe
                          - categoryId
                          - canConfirm
                          properties:
                            id:
                              type: string
                              format: uuid
                            nameSci:
                              type: string
                            nameEn:
                              type: string
                            nameDe:
                              type: string
                            categoryId:
                              type: string
                            familySci:
                              type: string
                            animal:
                              $ref: '#/components/schemas/AnimalSummary'
                            canConfirm:
                              type: boolean
                            reason:
                              type: string
                              enum:
                              - uncertain
                              - image_unavailable
                              - specialist_disagrees
                              - taxonomy_unavailable
                              - verification_unavailable
                      breedHints:
                        type: array
                        maxItems: 3
                        description: Possible domestic dog or cat breed appearance, matched to a sourced registry. A photo cannot confirm pedigree. Hints do not create catalog animals or rewards.
                        items:
                          type: object
                          required:
                          - id
                          - name
                          - parentNameSci
                          - sourceUrl
                          - registry
                          - status
                          properties:
                            id:
                              type: string
                            name:
                              type: string
                            parentNameSci:
                              type: string
                              enum:
                              - Canis familiaris
                              - Felis catus
                            sourceUrl:
                              type: string
                              format: uri
                            registry:
                              type: string
                              enum:
                              - FCI
                              - FIFe
                              - CFA
                            status:
                              type: string
                              enum:
                              - recognized
                              - provisional
                      excludedIds:
                        type: array
                        items:
                          type: string
                          pattern: ^[a-z0-9]+(-[a-z0-9]+)*$
                          description: Slug of the animal taxon, for example `red-fox`.
                          examples:
                          - red-fox
                      visibleFeatures:
                        type: array
                        items:
                          type: string
              example:
                data:
                  id: 7b0db8de-78b7-4c68-85d2-4877b5612aad
                  status: pending
                  excludedIds: []
        '400':
          description: Invalid input.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: INVALID_INPUT
                  message: 'page: Number must be at least 1'
        '401':
          description: Sign-in required.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: AUTH_REQUIRED
                  message: Sign in to your account
        '403':
          description: A same-origin request is required.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: INVALID_ORIGIN
                  message: Use this site
        '404':
          description: Not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: NOT_FOUND
                  message: Unknown animal
        '409':
          description: Account changed in another tab.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: ACCOUNT_SWITCH_REQUIRED
                  message: Refresh your account before changing data
        '429':
          description: Rate limited.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: RATE_LIMITED
                  message: Too many requests; try again later
          headers:
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait.
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimit-Policy'
        '500':
          description: Unexpected error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: INTERNAL
                  message: Unexpected error
  /recognitions/{id}/confirm:
    post:
      operationId: confirmRecognition
      summary: Confirm one species suggestion
      tags:
      - Recognition
      security:
      - sessionCookie: []
      description: The signed-in job owner confirms an unexpired candidate on the same origin. Repeated confirmation returns the same catalog animal. Missing species use a separately licensed CC0 or public-domain catalog photo. Uploaded photos are never stored or served.
      parameters:
      - name: X-Account-Id
        in: header
        required: true
        schema:
          type: string
          format: uuid
        description: Account id shown by GET /account. Prevents a browser session change from changing a different account.
      - name: id
        in: path
        required: true
        description: The owner's recognition job id.
        schema:
          type: string
          format: uuid
      - name: lang
        in: query
        required: false
        schema:
          type: string
          enum:
          - en
          - de
          - es
          - fr
          - it
          - nl
          - pt
          - pl
          default: en
          description: Display language of `name`, category labels and the summary. Falls back to `en`.
        description: Display language. Default `en`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - candidateId
              additionalProperties: false
              properties:
                candidateId:
                  type: string
                  format: uuid
      responses:
        '200':
          description: Confirmed catalog animal.
          headers:
            Deprecation:
              $ref: '#/components/headers/Deprecation'
            Sunset:
              $ref: '#/components/headers/Sunset'
          content:
            application/json:
              schema:
                type: object
                required:
                - data
                properties:
                  data:
                    type: object
                    required:
                    - animal
                    properties:
                      animal:
                        $ref: '#/components/schemas/AnimalSummary'
              example:
                data:
                  animal:
                    id: gbif-2435094
                    nameSci: Caracal caracal
        '400':
          description: Invalid input.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: INVALID_INPUT
                  message: 'page: Number must be at least 1'
        '401':
          description: Sign-in required.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: AUTH_REQUIRED
                  message: Sign in to your account
        '403':
          description: A same-origin request is required.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: INVALID_ORIGIN
                  message: Use this site
        '404':
          description: Unknown or expired candidate.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: NOT_FOUND
                  message: This suggestion has expired
        '409':
          description: Candidate cannot be imported, or its licensed catalog photo is no longer available.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: CANDIDATE_UNAVAILABLE
                  message: This suggestion cannot be added
        '429':
          description: Rate limited.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: RATE_LIMITED
                  message: Too many requests; try again later
          headers:
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait.
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimit-Policy'
        '500':
          description: Unexpected error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: INTERNAL
                  message: Unexpected error
components:
  schemas:
    AnimalSummary:
      type: object
      title: AnimalSummary
      description: Card-sized animal taxon used by list and search answers.
      required:
      - id
      - name
      - nameEn
      - nameSci
      - categoryId
      - habitats
      - image
      properties:
        id:
          type: string
          pattern: ^[a-z0-9]+(-[a-z0-9]+)*$
          description: Slug of the animal taxon, for example `red-fox`.
          examples:
          - red-fox
        name:
          type: string
          description: Name in the requested language, English when none exists.
        nameEn:
          type: string
          description: English common name.
        nameSci:
          type: string
          description: Scientific name.
          examples:
          - Vulpes vulpes
        taxonRank:
          type: string
          default: species
          description: Taxonomic rank. Legacy records default to species.
        parentNameSci:
          type:
          - string
          - 'null'
          description: Parent species scientific name for a subspecies. Null for species.
        categoryId:
          type: string
          enum:
          - mammals
          - birds
          - reptiles
          - amphibians
          - fish
          - insects
          - other
        habitats:
          type: array
          items:
            type: string
            enum:
            - forest
            - grassland
            - freshwater
            - sea
            - mountains
            - urban
            - farm
            - zoo
            - savanna
            - jungle
            - arctic
            - desert
        tickable:
          type: boolean
          description: Whether a new checklist sighting is allowed.
        sourceUrl:
          type: string
          format: uri
        image:
          type:
          - object
          - 'null'
          required:
          - url
          properties:
            url:
              type: string
              format: uri
    Error:
      type: object
      title: Error
      description: Every failure answers this shape. The status matches `error.code`.
      required:
      - error
      properties:
        error:
          type: object
          required:
          - code
          - message
          properties:
            code:
              type: string
              enum:
              - INVALID_INPUT
              - INVALID_JSON
              - UNKNOWN_CODE
              - UNKNOWN_ANIMAL
              - CANDIDATE_UNAVAILABLE
              - CANDIDATE_IMAGE_UNAVAILABLE
              - AUTH_REQUIRED
              - INVALID_ORIGIN
              - INVALID_BODY
              - INVALID_EMAIL
              - EMAIL_UNAVAILABLE
              - INVALID_LINK
              - INVALID_PASSKEY
              - INVALID_CHALLENGE
              - PASSKEY_LIMIT
              - PASSKEY_UNAVAILABLE
              - PASSKEY_NOT_FOUND
              - ACCOUNT_SWITCH_REQUIRED
              - ACCOUNT_LINKED
              - QUIZ_UNAVAILABLE
              - QUIZ_NOT_FOUND
              - QUIZ_EXPIRED
              - QUIZ_INCOMPLETE
              - QUIZ_ALREADY_SAVED
              - INVALID_ANSWER
              - QUIZ_ORDER
              - QUIZ_ANSWERED
              - MCP_KEY_LIMIT
              - NOT_FOUND
              - TOO_LARGE
              - RATE_LIMITED
              - INTERNAL
              description: Machine-readable reason.
            message:
              type: string
              description: One sentence for a human.
  headers:
    Sunset:
      schema:
        type: string
        format: http-date
      description: RFC 8594. Date the deprecated version stops answering.
    RateLimit-Policy:
      schema:
        type: string
      description: Quota policy of a metered endpoint, for example "accounts";q=20;w=3600.
    Deprecation:
      schema:
        type: string
      description: RFC 9745. Present on every answer of a deprecated version.
  securitySchemes:
    syncCode:
      type: http
      scheme: bearer
      bearerFormat: AC-XXXX-XXXX-XXXX-XXXX
      description: The person's anonymous sync code. It grants read and write access to that one checklist and nothing else. An agent uses a code only when the person supplied it.
    quizRound:
      type: http
      scheme: bearer
      bearerFormat: 43-character opaque round secret
      description: Keep this secret in local storage. Completed guest rounds remain claimable until deletion.
    sessionCookie:
      type: apiKey
      in: cookie
      name: ac_session
      description: HttpOnly session set after a magic link or passkey sign-in.
externalDocs:
  description: Agent guide
  url: https://animalchecklist.com/for-agents
x-authentication:
  scheme: public reads; sync code or session for sightings; session for recognition and account data
  description: Catalogue reads need no key or account. Sightings accept a sync code or the person's session cookie. Recognition, account and passkey management require a session cookie.
  docs: https://animalchecklist.com/for-agents
x-versioning-policy:
  scheme: url-path
  current: v1
  deprecation: A breaking change ships as a new path version. The old version answers with a Deprecation header (RFC 9745) and a Sunset header (RFC 8594) at least 180 days before removal.
  headers:
  - Deprecation
  - Sunset
  noticePeriodDays: 180
  docs: https://animalchecklist.com/for-agents
x-pagination:
  style: page
  description: Send `page` from 1 and `per` up to 120 for animals or 100 for registry endpoints. Default per is 60. Stop when page * per >= total.
  requestParameters:
  - page
  - per
  responseFields:
  - total
  - page
  - per
  endpoints:
  - /animals
  - /taxa
  - /breeds
x-batch-endpoints:
- path: /animals
  method: get
  operationId: getAnimalsByIds
  itemsField: ids
  maxItems: 500
  description: Reads up to 500 animals in one request with a comma separated `ids` list.
- path: /sightings
  method: put
  operationId: putSightings
  itemsField: sightings
  maxItems: 2000
  description: Merges up to 2000 sightings in one request.
x-rate-limit:
  description: Public catalogue reads use edge caching. POST /accounts allows 20 requests per IP per hour. POST /recognitions allows 10 per IP per hour, 20 per account per day, and 200 total per day. POST /client-error allows 30 per IP per hour.
  headers:
  - RateLimit-Policy
  - Retry-After
  accountsPerHour: 20
  clientErrorPerHour: 30
x-llms-txt: https://animalchecklist.com/llms.txt
x-agents-md: https://animalchecklist.com/agents.md
x-api-catalog: https://animalchecklist.com/.well-known/api-catalog
x-licence:
  scope: The info.license covers this API description. Response content keeps its source rights.
  terms: https://animalchecklist.com/licences
  photos: CC0, Public domain, Pexels License or Pixabay Content License; see each image record
  texts: Wikipedia excerpts, CC BY-SA 4.0. Keep attribution, licence link, changes and supplied notices. Check article exceptions.
  data: 'Structured Wikidata: CC0. iNaturalist taxonomy archive: no explicit licence supplied. Breed standards: source-specific rights.'