Operations 5
Documentation
Documentation
https://www.inaturalist.org/pages/api+reference
RateLimits
https://raw.githubusercontent.com/api-evangelist/inaturalist/main/rate-limits/rate-limits.yml
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
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.curl "https://apis.io/api/v1/apis/inaturalist-messages-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
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: 3.2.0
info:
title: iNaturalist Messages API
description: '# https://api.inaturalist.org/v1/
iNaturalist is a global community of
naturalists, scientists, and members of the public sharing over a million
wildlife sightings to teach one another about the natural world while
creating high quality citizen science data for science and conservation.'
version: 1.3.0
servers:
- url: /v1
tags:
- name: Messages
description: Create, fetch, delete
paths:
/messages:
get:
summary: Retrieve messages for the authenticated user. This does not mark them as read
description: Show the user's inbox or sent box
parameters:
- $ref: '#/components/parameters/page'
- name: box
in: query
description: Whether to view messages the user has received (default) or messages the user has sent
schema:
type: string
enum:
- inbox
- sent
- any
default: inbox
- name: q
in: query
description: Search query for subject and body
schema:
type: string
- name: user_id
in: query
description: User ID or username of correspondent to filter by
schema:
type: string
- name: threads
in: query
description: 'Groups results by `thread_id`, only shows the latest message per
thread, and includes a `thread_messages_count` attribute showing the
total number of messages in that thread. Note that this will not
work with the `q` param, and it probably should only be used with
`box=any` because the `thread_messages_count` will be inaccurate when
you restrict it to `inbox` or `sent`.
'
schema:
type: boolean
default: false
tags:
- Messages
security:
- api_token: []
responses:
'200':
description: OK
default:
description: 'Returns an object with metadata and an array of messages
'
content:
application/json:
schema:
$ref: '#/components/schemas/MessagesResponse'
operationId: getMessages
x-operation-id-source: derived
post:
summary: Create a new message
description: Create and deliver a new message to another user
tags:
- Messages
security:
- api_token: []
responses:
'200':
description: 'Returns the message just created
'
content:
application/json:
schema:
$ref: '#/components/schemas/Message'
default:
description: Unexpected error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PostMessage'
operationId: postMessages
x-operation-id-source: derived
/messages/{id}:
get:
summary: Retrieve messages in a thread
description: 'Retrieves all messages in the thread the specified message belongs to
and marks them all as read.'
tags:
- Messages
security:
- api_token: []
parameters:
- $ref: '#/components/parameters/path_id'
responses:
'200':
description: 'Returns an object with metadata and an array of messages
'
content:
application/json:
schema:
properties:
reply_to_user:
description: User to reply to
$ref: '#/components/schemas/User'
thread_id:
description: Identifier for this thread
type: integer
flaggable_message_id:
description: 'Identifier for the message that should be flagged if the user
chooses to flag this thread
'
type: integer
results:
type: array
items:
$ref: '#/components/schemas/Message'
default:
description: Unexpected error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
operationId: getMessagesById
x-operation-id-source: derived
delete:
summary: Delete a message / thread
description: 'This will all of the authenticated user''s copies of the messages in tha
thread to which the specified message belongs.'
tags:
- Messages
security:
- api_token: []
parameters:
- $ref: '#/components/parameters/path_id'
responses:
'200':
description: 'No return data, 200 just means deletion was successful
'
'404':
description: 'Specified message doesn''t exist
'
default:
description: Unexpected error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
operationId: deleteMessagesById
x-operation-id-source: derived
/messages/unread:
get:
summary: Gets a count of messages the authenticated user has not read
tags:
- Messages
security:
- api_token: []
responses:
'200':
description: Number of unread messages
content:
application/json:
schema:
properties:
count:
type: integer
description: Number of unread messages
default:
description: Unexpected error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
operationId: getMessagesUnread
x-operation-id-source: derived
components:
parameters:
path_id:
name: id
in: path
required: true
description: ID of the record
schema:
type: integer
page:
name: page
in: query
description: Pagination `page` number
schema:
type: string
schemas:
BaseResponse:
type: object
properties:
total_results:
type: integer
page:
type: integer
per_page:
type: integer
Message:
type: object
properties:
id:
type: integer
subject:
type: string
body:
type: string
user_id:
type: integer
description: 'ID of the user to whom this message belongs. Messages work like email,
so the sender gets a copy and the recipient gets a copy of each
message. This is always the authenticated user, so there''s no real
need for a full user object.
'
to_user:
$ref: '#/components/schemas/User'
from_user:
$ref: '#/components/schemas/User'
thread_id:
type: integer
description: 'Identifier for the message thread, generally the ID of the sender''s
copy of the first message
'
thread_messages_count:
type: integer
description: 'Number of messages in this thread. Only included when threads=true
'
thread_flags:
type: array
description: 'Array of flags on messages in this thread. Only included when
threads=true
'
items:
type: object
User:
type: object
properties:
created_at:
type: string
format: date-time
id:
type: integer
icon:
type: string
icon_url:
type: string
identifications_count:
type: integer
journal_posts_count:
type: integer
login:
type: string
name:
type: string
observations_count:
type: integer
orcid:
type: string
roles:
type: array
items:
type: string
enum:
- admin
- app owner
- curator
site_id:
type: integer
species_count:
type: integer
spam:
type: boolean
suspended:
type: boolean
Error:
type: object
properties:
code:
type: integer
message:
type: string
PostMessage:
type: object
properties:
message:
type: object
properties:
to_user_id:
type: integer
description: User ID of the recipient
thread_id:
type: integer
description: 'Identifier for the thread. Should be blank for new threads,
but when replying to an existing message, it should be set to
the thread_id of the message being replied to.
'
subject:
type: string
description: Subject of the message
body:
type: string
description: Body of the message
MessagesResponse:
allOf:
- $ref: '#/components/schemas/BaseResponse'
- required:
- results
properties:
results:
type: array
items:
$ref: '#/components/schemas/Message'
securitySchemes:
api_token:
type: apiKey
name: Authorization
in: header