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/esper:esper-apps-management-vpp-app-management-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: 3.2.0
info:
title: ESPER API REFERENCE apps_management_VPP App Management API
x-logo:
url: esper-logo-white.svg
backgroundColor: '#141418'
altText: Logo
description: '# Introduction
Welcome to Esper’s API documentation. The Esper API allows users to accomplish operations outside of the console. Some common uses for our APIs include observing device information and console activity, installing and updating apps, uploading files, and sending files to devices. Our users have also used the API to automate app updates, perform bulk actions, and more. Esper API endpoints use REST-based architecture and return JSON responses. See our documentation for:
* Getting started guides
* Commonly used API examples
* API command examples
* Automated Script examples
* And more
# Authentication
You need to create an API Key to interact with our APIs. Learn more about generating an API Key. You can also learn more about Esper and sign up for an account at esper.io/signup. Some endpoints also require an Enterprise ID. This ID can be found in the API Management section of the Esper console. # Lifecycle Labels
Esper uses lifecycle labels to communicate the support status of each API endpoint. Use the following table to understand what each label means and how to respond. Badge
What it means
Recommended action
Stable
This endpoint is fully supported and safe for production use. No action needed. Beta
This endpoint is publicly available but may change. It is not recommended for production integrations. Use with caution. Monitor the API changelog for updates before relying on this endpoint. Legacy
This endpoint uses an older architecture and is still supported, but a newer equivalent exists. It is not recommended for new integrations. Plan migration to the recommended replacement when possible. See the endpoint description for the alternative. Deprecated
This endpoint has stopped being supported. A removal date may be added at a later time. A replacement is available or the feature is entirely retired. Migrate before the removal date listed in the endpoint description. Do not use this endpoint in new integrations. # Pagination
Responses may be paginated. Use the following parameters to query the data. A full list of parameters can be found on the endpoint’s documentation page. Parameter
Data Type
Explanation
limit
integer
Limit the data returned. Default = 20. offset
integer
Offset to the first item returned. Default = 0. ordering
string
Order the results set by the field name. Varies by endpoint. next
string
Paginate to the next response set. previous
string
Paginate to the last set response. # Errors
We use standard HTTP status codes for success or failure. A typical error response may look something like this:
```json
{
"errors": [],
"message": "error message",
"status": 400
}
```
* `errors` - List of error details
* `message` - Error description
* `status` - HTTP status code
Some common status codes and messages are:
Number
Message
Explanation
200
OK
The request succeeded. 201
Resource creation
A resource was created. 401
Unauthorized
The API key is invalid. 404
Not found
The resource was not found. 429
Rate limit exceeded
Too many requests. Wait a moment and try again. 500
Server error
Internal error. Wait a moment and try again. If the issue persists, contact Esper. See how our systems are doing by checking our status page. # Rate Limits
To ensure quality of service for all customers, we enforce rate limits for API requests. Most customers won’t hit this limit with normal use. In case you experience 429 or rate limit exceeded errors, we recommend the following:
* Try sending requests in batches. * Begin with about 20 requests at a time and building up from there. * Ensure your scripts are efficient and don’t contain redundant calls. * Reach out to your account manager to discuss your options.'
termsOfService: https://esper.io/terms-of-service
contact:
email: developer@esper.io
license:
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
version: 1.0.0
x-prefix-tag: esper cloud api
servers:
- url: https://{foo}-api.esper.cloud/api
variables:
foo:
default: develop
description: Custom end point
tags:
- name: apps_management_VPP App Management
description: APIs for getting information about VPP apps. Learn more about VPP apps.
x-displayName: VPP App Management
paths:
/v2/itunesapps:
get:
x-badges:
- name: Stable
color: green
security:
- apps_management_apiKey: []
parameters:
- name: app_id
in: query
schema:
type: string
format: uuid
- name: version_id
in: query
schema:
type: string
format: uuid
- name: apple_app_id
in: query
schema:
type: string
- name: country_code
in: query
description: ISO country code for App Store region (e.g., "us", "gb", "de"). Defaults to "us".
schema:
type: string
pattern: ^[a-zA-Z]{2}$
example: us
summary: Get iOS App Info (v2)
description: 'Looks up iOS app information by app ID or Apple app ID.
Returns a paginated list of ItunesAppInfoV2 records — app name, icon, developer, current version, and iTunes Store URL — matched by Esper''s internal app_id, an Apple app ID, or a specific version_id, optionally scoped to an App Store country/region.
**About iOS App Info**
This is an iOS/VPP-specific endpoint (Android is not applicable) that surfaces iTunes/App Store metadata for apps managed through Esper''s VPP App Management. It''s the v2 replacement path for looking up iTunes app details tied to a tenant''s VPP-managed iOS apps.
**Key Fields / Query Parameters**
- app_id — Esper''s internal UUID for the app
- version_id — UUID of a specific app version
- apple_app_id — the app''s ID from Apple
- country_code — ISO country code for the App Store region, defaults to "us"
**Common Use Cases**
- Looking up current iTunes metadata (name, icon, version) for a VPP-managed iOS app
- Resolving an Apple app ID to Esper''s internal app_id for further API calls'
tags:
- apps_management_VPP App Management
responses:
'200':
description: Success
content:
application/json:
schema:
type: object
properties:
content:
type: object
properties:
count:
type: integer
description: number of results returned
prev:
type: string
description: URL for previous page of results
next:
type: string
description: URL for next page of results
results:
type: array
items:
oneOf:
- $ref: '#/components/schemas/apps_management_ItunesAppInfoV2'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/apps_management_Error_400_Bad_Data'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/apps_management_Error_401_Unauthorized'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/apps_management_Error_500_Internal_Server_Error'
operationId: getV2Itunesapps
x-operation-id-source: derived
/v2/itunesapps/{appleAppId}/preferred-region:
put:
x-badges:
- name: Stable
color: green
security:
- apps_management_apiKey: []
parameters:
- in: path
required: true
name: appleAppId
schema:
type: string
description: The Apple App Store ID of the VPP app (e.g., "361309726")
summary: Set Preferred Region for VPP App
description: '⚠️ Apple devices only. This endpoint applies exclusively to iOS devices managed via VPP (Volume Purchase Program).
Sets the preferred App Store region for a specific VPP app, overriding the default storefront used when Esper fetches app metadata and updates for that app.
Each VPP app can be assigned to one of the preferred regions configured at the tenant level. Assigning the correct region is important for update reliability — devices in a region that doesn''t match the app''s assigned storefront may fail to receive app updates.
**About VPP App Preferred Region**
Apple''s App Store is region-segmented; the same app may exist under different storefronts with different availability, pricing tiers, and update cadences. When managing VPP apps across a multi-region fleet, Esper needs to know which App Store storefront to use for each app. This endpoint sets that per-app region preference. The available regions to select from are those already configured at the tenant level via POST /v2/preferred-regions (up to five). In the Console, this setting is accessible when adding or editing an app under Apps > VPP Apps.
**Key Fields**
appleAppId (path, required) — the Apple numeric App Store ID for the VPP app (e.g., 361309726)
preferred_region (required) — ISO 3166-1 alpha-2 country code (uppercase) for the desired App Store storefront (e.g., "US", "GB", "AU"); must be one of the regions already added to the tenant''s preferred region list
**Common Use Cases**
Assigning each VPP app to the App Store storefront matching the primary device region where it is deployed
Correcting a region mismatch when devices in a specific country are failing to receive app updates
Reconfiguring app storefronts after an organizational expansion into a new country
Best Practices
Only assign a region that is already in the tenant''s configured preferred region list — the available options are set via POST /v2/preferred-regions
Match the app''s region to the physical operating region of the devices it is assigned to, not the billing region of the VPP token
Audit per-app region assignments when expanding into new countries to prevent silent update failures
Workflow
Confirm the desired country is in the tenant''s preferred region list via GET /v2/preferred-regions
PUT to /v2/itunesapps/{appleAppId}/preferred-region with { "preferred_region": "US" } (or the appropriate code)
Verify the response message confirms success; subsequently, device updates for that app will use the assigned storefront'
tags:
- apps_management_VPP App Management
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/apps_management_SetPreferredRegionRequest'
responses:
'200':
description: Success
content:
application/json:
schema:
type: object
properties:
content:
type: object
properties:
message:
type: string
example: Preferred region updated successfully
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/apps_management_Error_400_Bad_Data'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/apps_management_Error_401_Unauthorized'
'404':
description: Not Found
content:
application/json:
schema:
$ref: '#/components/schemas/apps_management_Error_404_Not_Found'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/apps_management_Error_500_Internal_Server_Error'
operationId: putV2ItunesappsByAppleAppIdPreferredRegion
x-operation-id-source: derived
/v2/itunesapps/{appId}/refresh-version:
post:
x-badges:
- name: Stable
color: green
security:
- apps_management_apiKey: []
parameters:
- in: path
required: true
name: appId
schema:
type: string
format: uuid
description: The internal Esper app id (UUID) of the VPP app
summary: Force refresh of VPP app version metadata
description: 'Forces an on-demand refresh of a single VPP app''s iTunes version metadata.
Synchronously re-fetches the latest iTunes metadata for the given app under the caller''s tenant and persists it, using the same write path as the daily VPP version cron job, but scoped to just that one (tenant, app_id) pair. Returns the refreshed app details directly so callers can render updated info without a follow-up GET.
**About VPP App Refresh**
VPP apps are normally kept in sync with Apple''s iTunes catalog via a daily background cron job; this endpoint lets a caller trigger that same sync immediately for a single app rather than waiting for the next scheduled run.
**Key Fields / Query Parameters**
- appId — UUID of the VPP app to refresh, passed in the path
**Common Use Cases**
- Immediately pulling a newly released app version''s metadata into Esper instead of waiting for the daily cron
- Refreshing stale iTunes metadata (icon, version, size) for a specific app right before deployment
**Best Practices**
- Use this for one-off, on-demand refreshes rather than as a substitute for the daily sync — it''s scoped to a single app, not the full catalog
Synchronously re-fetches the latest iTunes metadata for a single VPP
app under the caller''s tenant and persists it. Same write path as the
daily VPP version cron, scoped to one (tenant, app_id). Returns
the refreshed app details so the UI can render without a follow-up GET.'
tags:
- apps_management_VPP App Management
responses:
'200':
description: Success
content:
application/json:
schema:
type: object
properties:
content:
$ref: '#/components/schemas/apps_management_ItunesAppInfoV2'
'400':
description: Bad Request (invalid app_id or missing headers)
content:
application/json:
schema:
$ref: '#/components/schemas/apps_management_Error_400_Bad_Data'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/apps_management_Error_401_Unauthorized'
'404':
description: Not Found (no vpp_app_ids row for the tenant + app_id, or app not found in iTunes)
content:
application/json:
schema:
$ref: '#/components/schemas/apps_management_Error_404_Not_Found'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/apps_management_Error_500_Internal_Server_Error'
operationId: postV2ItunesappsByAppIdRefreshVersion
x-operation-id-source: derived
components:
schemas:
apps_management_Error_404_Not_Found:
type: object
properties:
code:
type: integer
format: int32
default: 404
message:
type: string
content:
type: object
required:
- code
- message
apps_management_Error_400_Bad_Data:
type: object
properties:
code:
type: integer
format: int32
default: 400
message:
type: string
content:
type: object
required:
- code
- message
apps_management_Error_500_Internal_Server_Error:
type: object
properties:
code:
type: integer
format: int32
default: 500
message:
type: string
content:
type: object
required:
- code
- message
apps_management_ItunesAppInfoV2:
type: object
properties:
app_id:
type: string
format: uuid
description: App ID in UUID format
apple_app_id:
type: string
description: App ID from Apple
app_version_id:
type: string
format: uuid
description: current version of the app in UUID format
apple_app_version:
type: string
description: current version of the app
app_name:
type: string
description: name of the app
icon_url:
type: string
description: url of the app's icon
developer:
type: string
description: developer of the app
itunes_url:
type: string
description: URL for the app on the iTunes store
genres:
type: array
items:
type: string
description: genre of the app
device_families:
type: array
items:
type: string
description: devices the app is compatible with
bundle_id:
type: string
description: bundle ID of the app
price:
type: number
description: price of the app
app_size:
type: integer
description: size of the app
minimum_os_version:
type: string
description: minimum OS version required for the app
description:
type: string
description: description of the app
last_updated_date:
type: string
description: date the app was last updated
pricing_param:
type: string
description: pricing parameter
apps_management_SetPreferredRegionRequest:
type: object
required:
- preferred_region
properties:
preferred_region:
type: string
pattern: ^[a-zA-Z]{2}$
description: ISO 3166-1 alpha-2 country code for the preferred App Store region (e.g., 'US', 'JP')
example: US
apps_management_Error_401_Unauthorized:
type: object
properties:
code:
type: integer
format: int32
default: 401
message:
type: string
content:
type: object
required:
- code
- message
securitySchemes:
esper_cloud_api_apiKey:
type: http
scheme: bearer
description: "#### API KEY - Access Token\nAccess token for API is passed as authorization header in calls. You need to generate this from your Esper Console at `<domain>-api.esper.cloud` where foo is the sub-domain name you gave for your Esper Dev environment when you signed up for your Esper account. Please follow the instructions [in this Help article](https://help.esper.io/hc/en-us/articles/12656959508497) to generate an access token.\nOnce you have the access token, you need to send an authorization header as below\n\n```bash\n\n curl -X GET \\\n https://<domain>-api.esper.cloud/api/enterprise/<enterprise_id>/device/ \\\n -H 'Authorization: Bearer <ACCESS_TOKEN>' \\\n -H 'Content-Type: application/json' \\\n```\n\n> Please note the use of keyword **Bearer** before the token value.\n\n\nYou can read more about api key authentication [here](https://help.esper.io/hc/en-us/articles/12656959508497).\n"
pipelines_SCAPIAuthToken:
type: http
scheme: bearer
device_apiKey:
type: http
scheme: bearer
description: "#### API KEY - Access Token\nAccess token for API is passed as authorization header in calls. You need to generate this from your Esper Console at `<domain>-api.esper.cloud` where foo is the sub-domain name you gave for your Esper Dev environment when you signed up for your Esper account. Please follow the instructions [in this Help article](https://help.esper.io/hc/en-us/articles/12656959508497) to generate an access token.\nOnce you have the access token, you need to send an authorization header as below\n\n```bash\n\n curl -X GET \\\n https://<domain>-api.esper.cloud/api/enterprise/<enterprise_id>/device/ \\\n -H 'Authorization: Bearer <ACCESS_TOKEN>' \\\n -H 'Content-Type: application/json' \\\n```\n\n> Please note the use of keyword **Bearer** before the token value.\n\n\nYou can read more about api key authentication [here](https://help.esper.io/hc/en-us/articles/12656959508497).\n"
apps_management_apiKey:
type: http
scheme: bearer
description: "#### API KEY - Access Token\nAccess token for API is passed as authorization header in calls. You need to generate this from your Esper Console at `<domain>-api.esper.cloud` where foo is the sub-domain name you gave for your Esper Dev environment when you signed up for your Esper account. Please follow the instructions [in this Help article](https://help.esper.io/hc/en-us/articles/12656959508497) to generate an access token.\nOnce you have the access token, you need to send an authorization header as below\n\n```bash\n\n curl -X GET \\\n https://<domain>-api.esper.cloud/api/enterprise/<enterprise_id>/device/ \\\n -H 'Authorization: Bearer <ACCESS_TOKEN>' \\\n -H 'Content-Type: application/json' \\\n```\n\n> Please note the use of keyword **Bearer** before the token value.\n\n\nYou can read more about api key authentication [here](https://help.esper.io/hc/en-us/articles/12656959508497).\n"
commands_apiKey:
type: http
scheme: bearer
description: "#### API KEY - Access Token\nAccess token for API is passed as authorization header in calls. You need to generate this from your Esper Console at `<domain>-api.esper.cloud` where foo is the sub-domain name you gave for your Esper Dev environment when you signed up for your Esper account. Please follow the instructions [in this Help article](https://help.esper.io/hc/en-us/articles/12656959508497) to generate an access token.\nOnce you have the access token, you need to send an authorization header as below\n\n```bash\n\n curl -X GET \\\n https://<domain>-api.esper.cloud/api/enterprise/<enterprise_id>/device/ \\\n -H 'Authorization: Bearer <ACCESS_TOKEN>' \\\n -H 'Content-Type: application/json' \\\n```\n\n> Please note the use of keyword **Bearer** before the token value.\n\n\nYou can read more about api key authentication [here](https://help.esper.io/hc/en-us/articles/12656959508497).\n"
drift_apiKey:
type: http
scheme: bearer
description: "#### API KEY - Access Token\nAccess token for API is passed as authorization header in calls. You need to generate this from your Esper Console at `<domain>-api.esper.cloud` where foo is the sub-domain name you gave for your Esper Dev environment when you signed up for your Esper account. Please follow the instructions [in this Help article](https://help.esper.io/hc/en-us/articles/12656959508497) to generate an access token.\nOnce you have the access token, you need to send an authorization header as below\n\n```bash\n\n curl -X GET \\\n https://<domain>-api.esper.cloud/api/enterprise/<enterprise_id>/device/ \\\n -H 'Authorization: Bearer <ACCESS_TOKEN>' \\\n -H 'Content-Type: application/json' \\\n```\n\n> Please note the use of keyword **Bearer** before the token value.\n\n\nYou can read more about api key authentication [here](https://help.esper.io/hc/en-us/articles/12656959508497).\n"
device_onboarding_apiKey:
type: http
scheme: bearer
description: "#### API KEY - Access Token\nAccess token for API is passed as authorization header in calls. You need to generate this from your Esper Console at `<domain>-api.esper.cloud` where foo is the sub-domain name you gave for your Esper Dev environment when you signed up for your Esper account. Please follow the instructions [in this Help article](https://help.esper.io/hc/en-us/articles/12656959508497) to generate an access token.\nOnce you have the access token, you need to send an authorization header as below\n\n```bash\n\n curl -X GET \\\n https://<domain>-api.esper.cloud/api/enterprise/<enterprise_id>/device/ \\\n -H 'Authorization: Bearer <ACCESS_TOKEN>' \\\n -H 'Content-Type: application/json' \\\n```\n\n> Please note the use of keyword **Bearer** before the token value.\n\n\nYou can read more about api key authentication [here](https://help.esper.io/hc/en-us/articles/12656959508497).\n"
tenant_apiKey:
type: http
scheme: bearer
description: "#### API KEY - Access Token\nAccess token for API is passed as authorization header in calls. You need to generate this from your Esper Console at `<domain>-api.esper.cloud` where foo is the sub-domain name you gave for your Esper Dev environment when you signed up for your Esper account. Please follow the instructions [in this Help article](https://help.esper.io/hc/en-us/articles/12656959508497) to generate an access token.\nOnce you have the access token, you need to send an authorization header as below\n\n```bash\n\n curl -X GET \\\n https://<domain>-api.esper.cloud/api/enterprise/<enterprise_id>/device/ \\\n -H 'Authorization: Bearer <ACCESS_TOKEN>' \\\n -H 'Content-Type: application/json' \\\n```\n\n> Please note the use of keyword **Bearer** before the token value.\n\n\nYou can read more about api key authentication [here](https://help.esper.io/hc/en-us/articles/12656959508497).\n"
foundation_AuthToken:
type: apiKey
in: header
name: Authorization
reports_bearerAuth:
type: http
scheme: bearer
geofence_bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
x-tagGroups:
- name: ESPER CLOUD API
tags:
- esper_cloud_api_Company Settings
- esper_cloud_api_Application
- esper_cloud_api_Application V1
- esper_cloud_api_AndroidDevice
- esper_cloud_api_Device Group
- esper_cloud_api_Token (Deprecated)
- esper_cloud_api_Commands V2
- esper_cloud_api_Enterprise Policy
- esper_cloud_api_Geofence
- esper_cloud_api_Content
- esper_cloud_api_User (Deprecated)
- esper_cloud_api_User
- esper_cloud_api_Blueprint (Deprecated)
- esper_cloud_api_Directory Record
- esper_cloud_api_Tile Icon
- esper_cloud_api_Alerts
- esper_cloud_api_Alarms
- esper_cloud_api_Wallpapers
- esper_cloud_api_Device Telemetry
- esper_cloud_api_Daily and Custom Reports
- esper_cloud_api_SSO Connections
- esper_cloud_api_Roles
- esper_cloud_api_Personal Access Token
- name: BLUEPRINTS
tags:
- blueprints_Blueprints API
- blueprints_Custom Actions API
- blueprints_Background Scripts API
- name: PIPELINES
tags:
- pipelines_System Status Code
- pipelines_System
- pipelines_Pipelines
- pipelines_Stages
- pipelines_Target Lists
- pipelines_Targets
- pipelines_Device Groups
- pipelines_Operation Lists
- pipelines_Operations
- pipelines_Pipeline Runs
- pipelines_Stage Runs
- pipelines_Target Runs
- name: DEVICE
tags:
- device_Device
- device_Device Heartbeat
- device_Device Apps
- device_Device Enrollment in EMM
- device_Operations
- device_DeviceOperations
- device_MultiOS Remote Viewer
- name: APPS MANAGEMENT
tags:
- apps_management_VPP License Management
- apps_management_VPP App Management
- apps_management_Tenant Apps
- apps_management_Apple App Store
- apps_management_App List
- apps_management_Webclips
- apps_management_Provisioning Profiles
- apps_management_Preferred Regions
- apps_management_OEM Config Schema
- apps_management_Esper Apps
- apps_management_Tenant Esper Apps
- name: COMMANDS
tags:
- commands_Command Request
- commands_Command Status
- name: DRIFT
tags:
- drift_Converge
- drift_Converge Command
- drift_Blueprint Drift
- name: DEVICE ONBOARDING
tags:
- device_onboarding_DEP Sync Request
- device_onboarding_ABM Provisioning
- name: TENANT
tags:
- tenant_APNs certificate
- tenant_DEP Profile
- tenant_DEP Tokens
- tenant_VPP Token Management
- tenant_Google Enterprise
- tenant_MDM Service Config
- name: FOUNDATION
tags:
- foundation_FoundryBuilds
- foundation_FoundryDeviceModels
- foundation_FoundryEvents
- name: REPORTS
tags:
- reports_Reports API
- name: GEOFENCE
tags:
- geofence_Geofences
- geofence_Device State
x-provenance:
method: harvested
publisher: Esper
source: https://api.esper.io/_bundle/openapi.json?download
note: split by refine-openapis from the provider's own published document, verified by fetch (openapi/_original/*.fetch.json);
stamped by stamp-openapi-provenance.py (roadmap#793)