Skip to content

Instantly share code, notes, and snippets.

@RhysSullivan
Created February 18, 2026 18:16
Show Gist options
  • Select an option

  • Save RhysSullivan/a38364ea69c92220ca8a9e5ec1370e8d to your computer and use it in GitHub Desktop.

Select an option

Save RhysSullivan/a38364ea69c92220ca8a9e5ec1370e8d to your computer and use it in GitHub Desktop.
openapi: 3.1.0
info:
title: Pushover API (Unofficial)
version: "1.0.0"
description: |
Unofficial OpenAPI spec for Pushover, derived from Pushover documentation.
Supports form-encoded, JSON, and multipart (attachments) for messages.
servers:
- url: https://api.pushover.net
tags:
- name: Messages
- name: Users
- name: Apps
- name: Receipts
- name: Groups
- name: Glances
- name: Teams
paths:
/1/messages.json:
post:
tags: [Messages]
summary: Send a notification message
description: |
Send a message to a user key or group key.
Supports x-www-form-urlencoded or JSON; use multipart/form-data to send a binary attachment,
or use attachment_base64 + attachment_type for JSON / non-multipart clients.
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema: { $ref: "#/components/schemas/MessageRequest" }
application/json:
schema: { $ref: "#/components/schemas/MessageRequest" }
multipart/form-data:
schema: { $ref: "#/components/schemas/MessageRequestMultipart" }
responses:
"200":
description: Accepted / queued
content:
application/json:
schema: { $ref: "#/components/schemas/MessageResponse" }
"4XX":
description: Invalid input / over quota
content:
application/json:
schema: { $ref: "#/components/schemas/ErrorResponse" }
/1/sounds.json:
get:
tags: [Messages]
summary: List available sounds
parameters:
- $ref: "#/components/parameters/AppTokenQuery"
responses:
"200":
description: Sound list
content:
application/json:
schema: { $ref: "#/components/schemas/SoundsResponse" }
"4XX":
description: Error
content:
application/json:
schema: { $ref: "#/components/schemas/ErrorResponse" }
/1/apps/limits.json:
get:
tags: [Apps]
summary: Get app monthly message limits/remaining/reset
parameters:
- $ref: "#/components/parameters/AppTokenQuery"
responses:
"200":
description: Limits
content:
application/json:
schema: { $ref: "#/components/schemas/LimitsResponse" }
"4XX":
description: Error
content:
application/json:
schema: { $ref: "#/components/schemas/ErrorResponse" }
/1/users/validate.json:
post:
tags: [Users]
summary: Validate a user or group key (optionally device)
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema: { $ref: "#/components/schemas/ValidateRequest" }
application/json:
schema: { $ref: "#/components/schemas/ValidateRequest" }
responses:
"200":
description: Validation result
content:
application/json:
schema: { $ref: "#/components/schemas/ValidateResponse" }
"4XX":
description: Error
content:
application/json:
schema: { $ref: "#/components/schemas/ErrorResponse" }
/1/receipts/{receipt}.json:
get:
tags: [Receipts]
summary: Get receipt status for an emergency-priority message
parameters:
- $ref: "#/components/parameters/ReceiptPath"
- $ref: "#/components/parameters/AppTokenQuery"
responses:
"200":
description: Receipt status
content:
application/json:
schema: { $ref: "#/components/schemas/ReceiptResponse" }
"4XX":
description: Error
content:
application/json:
schema: { $ref: "#/components/schemas/ErrorResponse" }
/1/receipts/{receipt}/cancel.json:
post:
tags: [Receipts]
summary: Cancel emergency-priority retries for a receipt
parameters:
- $ref: "#/components/parameters/ReceiptPath"
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema: { $ref: "#/components/schemas/TokenOnlyRequest" }
application/json:
schema: { $ref: "#/components/schemas/TokenOnlyRequest" }
responses:
"200":
description: Canceled
content:
application/json:
schema: { $ref: "#/components/schemas/OkResponse" }
"4XX":
description: Error
content:
application/json:
schema: { $ref: "#/components/schemas/ErrorResponse" }
/1/receipts/cancel_by_tag/{tag}.json:
post:
tags: [Receipts]
summary: Cancel emergency-priority retries by tag
parameters:
- $ref: "#/components/parameters/TagPath"
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema: { $ref: "#/components/schemas/TokenOnlyRequest" }
application/json:
schema: { $ref: "#/components/schemas/TokenOnlyRequest" }
responses:
"200":
description: Canceled
content:
application/json:
schema: { $ref: "#/components/schemas/OkResponse" }
"4XX":
description: Error
content:
application/json:
schema: { $ref: "#/components/schemas/ErrorResponse" }
/1/groups.json:
get:
tags: [Groups]
summary: List delivery groups on the account
parameters:
- $ref: "#/components/parameters/AppTokenQuery"
responses:
"200":
description: Group list
content:
application/json:
schema: { $ref: "#/components/schemas/GroupsListResponse" }
"4XX":
description: Error
content:
application/json:
schema: { $ref: "#/components/schemas/ErrorResponse" }
post:
tags: [Groups]
summary: Create a delivery group
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema: { $ref: "#/components/schemas/CreateGroupRequest" }
application/json:
schema: { $ref: "#/components/schemas/CreateGroupRequest" }
responses:
"200":
description: Created
content:
application/json:
schema: { $ref: "#/components/schemas/CreateGroupResponse" }
"4XX":
description: Error
content:
application/json:
schema: { $ref: "#/components/schemas/ErrorResponse" }
/1/groups/{group}.json:
get:
tags: [Groups]
summary: Get group info and members
parameters:
- $ref: "#/components/parameters/GroupPath"
- $ref: "#/components/parameters/AppTokenQuery"
responses:
"200":
description: Group details
content:
application/json:
schema: { $ref: "#/components/schemas/GroupInfoResponse" }
"4XX":
description: Error
content:
application/json:
schema: { $ref: "#/components/schemas/ErrorResponse" }
/1/groups/{group}/add_user.json:
post:
tags: [Groups]
summary: Add a user to a group
parameters:
- $ref: "#/components/parameters/GroupPath"
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema: { $ref: "#/components/schemas/GroupUserRequest" }
application/json:
schema: { $ref: "#/components/schemas/GroupUserRequest" }
responses:
"200":
description: Added
content:
application/json:
schema: { $ref: "#/components/schemas/OkResponse" }
"4XX":
description: Error
content:
application/json:
schema: { $ref: "#/components/schemas/ErrorResponse" }
/1/groups/{group}/remove_user.json:
post:
tags: [Groups]
summary: Remove a user from a group
parameters:
- $ref: "#/components/parameters/GroupPath"
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema: { $ref: "#/components/schemas/GroupUserRemoveRequest" }
application/json:
schema: { $ref: "#/components/schemas/GroupUserRemoveRequest" }
responses:
"200":
description: Removed
content:
application/json:
schema: { $ref: "#/components/schemas/OkResponse" }
"4XX":
description: Error
content:
application/json:
schema: { $ref: "#/components/schemas/ErrorResponse" }
/1/groups/{group}/disable_user.json:
post:
tags: [Groups]
summary: Disable a user in a group
parameters:
- $ref: "#/components/parameters/GroupPath"
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema: { $ref: "#/components/schemas/GroupUserDisableEnableRequest" }
application/json:
schema: { $ref: "#/components/schemas/GroupUserDisableEnableRequest" }
responses:
"200":
description: Disabled
content:
application/json:
schema: { $ref: "#/components/schemas/OkResponse" }
"4XX":
description: Error
content:
application/json:
schema: { $ref: "#/components/schemas/ErrorResponse" }
/1/groups/{group}/enable_user.json:
post:
tags: [Groups]
summary: Re-enable a user in a group
parameters:
- $ref: "#/components/parameters/GroupPath"
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema: { $ref: "#/components/schemas/GroupUserDisableEnableRequest" }
application/json:
schema: { $ref: "#/components/schemas/GroupUserDisableEnableRequest" }
responses:
"200":
description: Enabled
content:
application/json:
schema: { $ref: "#/components/schemas/OkResponse" }
"4XX":
description: Error
content:
application/json:
schema: { $ref: "#/components/schemas/ErrorResponse" }
/1/groups/{group}/rename.json:
post:
tags: [Groups]
summary: Rename a group
parameters:
- $ref: "#/components/parameters/GroupPath"
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema: { $ref: "#/components/schemas/RenameGroupRequest" }
application/json:
schema: { $ref: "#/components/schemas/RenameGroupRequest" }
responses:
"200":
description: Renamed
content:
application/json:
schema: { $ref: "#/components/schemas/OkResponse" }
"4XX":
description: Error
content:
application/json:
schema: { $ref: "#/components/schemas/ErrorResponse" }
/1/glances.json:
post:
tags: [Glances]
summary: Update glance/widget data
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema: { $ref: "#/components/schemas/GlanceRequest" }
application/json:
schema: { $ref: "#/components/schemas/GlanceRequest" }
responses:
"200":
description: Updated
content:
application/json:
schema: { $ref: "#/components/schemas/OkResponse" }
"4XX":
description: Error
content:
application/json:
schema: { $ref: "#/components/schemas/ErrorResponse" }
/1/teams.json:
get:
tags: [Teams]
summary: Show team info (requires team token)
parameters:
- $ref: "#/components/parameters/TeamTokenQuery"
responses:
"200":
description: Team info
content:
application/json:
schema: { $ref: "#/components/schemas/TeamInfoResponse" }
"4XX":
description: Error
content:
application/json:
schema: { $ref: "#/components/schemas/ErrorResponse" }
/1/teams/add_user.json:
post:
tags: [Teams]
summary: Add a user to a team (requires team token)
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema: { $ref: "#/components/schemas/TeamAddUserRequest" }
application/json:
schema: { $ref: "#/components/schemas/TeamAddUserRequest" }
responses:
"200":
description: Added
content:
application/json:
schema: { $ref: "#/components/schemas/OkResponse" }
"4XX":
description: Error
content:
application/json:
schema: { $ref: "#/components/schemas/ErrorResponse" }
/1/teams/remove_user.json:
post:
tags: [Teams]
summary: Remove a user from a team (requires team token)
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema: { $ref: "#/components/schemas/TeamRemoveUserRequest" }
application/json:
schema: { $ref: "#/components/schemas/TeamRemoveUserRequest" }
responses:
"200":
description: Removed
content:
application/json:
schema: { $ref: "#/components/schemas/OkResponse" }
"4XX":
description: Error
content:
application/json:
schema: { $ref: "#/components/schemas/ErrorResponse" }
components:
parameters:
AppTokenQuery:
name: token
in: query
required: true
schema: { type: string }
description: Application API token
TeamTokenQuery:
name: token
in: query
required: true
schema: { type: string }
description: Team API token (not an application token)
ReceiptPath:
name: receipt
in: path
required: true
schema: { type: string, minLength: 1 }
TagPath:
name: tag
in: path
required: true
schema: { type: string, minLength: 1 }
GroupPath:
name: group
in: path
required: true
schema: { type: string, minLength: 1 }
schemas:
OkResponse:
type: object
required: [status, request]
properties:
status: { type: integer, const: 1 }
request: { type: string }
additionalProperties: true
ErrorResponse:
type: object
required: [status, request]
properties:
status: { type: integer, description: "Non-1 indicates error" }
request: { type: string }
errors:
type: array
items: { type: string }
additionalProperties: true
TokenOnlyRequest:
type: object
required: [token]
properties:
token: { type: string }
MessageRequest:
type: object
required: [token, user, message]
properties:
token: { type: string, description: "Application API token" }
user: { type: string, description: "User key or group key" }
message: { type: string, description: "Message body" }
title: { type: string }
device: { type: string, description: "Target device name" }
url: { type: string }
url_title: { type: string }
priority:
type: integer
enum: [-2, -1, 0, 1, 2]
sound: { type: string }
timestamp: { type: integer, format: int64 }
html:
type: integer
enum: [0, 1]
monospace:
type: integer
enum: [0, 1]
ttl: { type: integer, format: int64, minimum: 0 }
# Emergency-priority extras
retry: { type: integer, format: int64, minimum: 0 }
expire: { type: integer, format: int64, minimum: 0 }
callback: { type: string, format: uri }
tags: { type: string, description: "Comma-separated tags" }
# Attachment (non-binary)
attachment_base64: { type: string, description: "Base64 image" }
attachment_type: { type: string, description: "MIME type for attachment_base64" }
additionalProperties: false
MessageRequestMultipart:
allOf:
- $ref: "#/components/schemas/MessageRequest"
- type: object
properties:
attachment:
type: string
format: binary
description: "Binary image attachment (multipart/form-data)"
additionalProperties: false
MessageResponse:
type: object
required: [status, request]
properties:
status: { type: integer, const: 1 }
request: { type: string }
receipt:
type: string
description: "Present for priority=2 (emergency) messages"
additionalProperties: true
SoundsResponse:
type: object
required: [status, request, sounds]
properties:
status: { type: integer, const: 1 }
request: { type: string }
sounds:
type: object
additionalProperties: { type: string }
additionalProperties: true
LimitsResponse:
type: object
required: [status, request, limit, remaining, reset]
properties:
status: { type: integer, const: 1 }
request: { type: string }
limit: { type: integer, format: int64 }
remaining: { type: integer, format: int64 }
reset: { type: integer, format: int64, description: "Unix timestamp" }
additionalProperties: true
ValidateRequest:
type: object
required: [token, user]
properties:
token: { type: string }
user: { type: string }
device: { type: string }
additionalProperties: false
ValidateResponse:
type: object
required: [status, request]
properties:
status: { type: integer }
request: { type: string }
devices:
type: array
items: { type: string }
licenses:
type: array
items: { type: string }
additionalProperties: true
ReceiptResponse:
type: object
required: [status]
properties:
status: { type: integer }
acknowledged: { type: integer, enum: [0, 1] }
acknowledged_at: { type: integer, format: int64 }
acknowledged_by: { type: string }
acknowledged_by_device: { type: string }
last_delivered_at: { type: integer, format: int64 }
expired: { type: integer, enum: [0, 1] }
expires_at: { type: integer, format: int64 }
called_back: { type: integer, enum: [0, 1] }
called_back_at: { type: integer, format: int64 }
additionalProperties: true
CreateGroupRequest:
type: object
required: [token, name]
properties:
token: { type: string }
name: { type: string }
additionalProperties: false
CreateGroupResponse:
type: object
required: [status, request, group]
properties:
status: { type: integer, const: 1 }
request: { type: string }
group: { type: string }
additionalProperties: true
GroupsListResponse:
type: object
required: [status, request, groups]
properties:
status: { type: integer, const: 1 }
request: { type: string }
groups:
type: array
items:
type: object
required: [group, name]
properties:
group: { type: string }
name: { type: string }
additionalProperties: true
additionalProperties: true
GroupInfoResponse:
type: object
required: [status, request, name, users]
properties:
status: { type: integer, const: 1 }
request: { type: string }
name: { type: string }
users:
type: array
items:
type: object
required: [user, disabled]
properties:
user: { type: string }
device: { type: ["string", "null"] }
memo: { type: ["string", "null"] }
disabled: { type: boolean }
name: { type: string }
email: { type: string }
additionalProperties: true
additionalProperties: true
GroupUserRequest:
type: object
required: [token, user]
properties:
token: { type: string }
user: { type: string }
device: { type: string }
memo: { type: string }
additionalProperties: false
GroupUserRemoveRequest:
type: object
required: [token, user]
properties:
token: { type: string }
user: { type: string }
device: { type: string }
additionalProperties: false
GroupUserDisableEnableRequest:
type: object
required: [token, user]
properties:
token: { type: string }
user: { type: string }
device: { type: string }
additionalProperties: false
RenameGroupRequest:
type: object
required: [token, name]
properties:
token: { type: string }
name: { type: string }
additionalProperties: false
GlanceRequest:
type: object
required: [token, user]
anyOf:
- required: [title]
- required: [text]
- required: [subtext]
- required: [count]
- required: [percent]
properties:
token: { type: string }
user: { type: string }
device: { type: string }
title: { type: string, maxLength: 100 }
text: { type: string, maxLength: 100 }
subtext: { type: string, maxLength: 100 }
count: { type: integer }
percent: { type: integer, minimum: 0, maximum: 100 }
additionalProperties: false
TeamInfoResponse:
type: object
required: [status, request, name, users]
properties:
status: { type: integer, const: 1 }
request: { type: string }
name: { type: string }
users:
type: array
items:
type: object
required: [id, email, administrator]
properties:
id: { type: string }
name: { type: string }
email: { type: string }
administrator: { type: boolean }
devices:
type: array
items:
type: object
properties:
name: { type: string }
os: { type: string }
os_version: { type: string }
enabled: { type: boolean }
administratively_disabled: { type: boolean }
additionalProperties: true
additionalProperties: true
additionalProperties: true
TeamAddUserRequest:
type: object
required: [token, email]
properties:
token: { type: string, description: "Team token" }
email: { type: string, format: email }
name: { type: string }
password: { type: string }
instant: { type: string, enum: ["true", "false"] }
admin: { type: string, enum: ["true", "false"] }
group: { type: string }
additionalProperties: false
TeamRemoveUserRequest:
type: object
required: [token, email]
properties:
token: { type: string, description: "Team token" }
email: { type: string, format: email }
additionalProperties: false
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment