Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: Jumpseller Appointments API
description: 'The Jumpseller API lets you read and manage a store''s products, orders, customers, shipping, promotions and more, so you can build Apps or connect a store to invoicing, ERP, CRM and other systems. # Endpoint Structure
All URLs follow this format:
```text
https://api.jumpseller.com/v1/{path}.json
```
For example, to list the products of your store:
```text
https://api.jumpseller.com/v1/products.json
```
The current version of the API is **v1**. If we change the API in backward-incompatible ways, we will release a new version and keep the old URLs working. # Authentication
There are two ways to authenticate:
* **API credentials** (login and auth token), to connect your own store to another system. * **OAuth 2.0**, required for Jumpseller Apps that other merchants install. Every request is made on behalf of one store. A request without valid credentials gets `403 Forbidden`. ## API credentials
Each account of a store has its own **login** and **auth token**. To find them, open your Admin Panel and go to **Account → Preferences** in the menu. The **API and MCP** card shows the login. Click **Show token** and confirm your password to see the auth token. **Reset** replaces the auth token, and the old one stops working at once. !API credentials in the Admin Panel
A request made with API credentials has the same permissions as the account that owns them. An account without the *Products* permission, for example, gets `403 Forbidden` on the product endpoints. ### Basic Authentication (recommended)
Send the login as the username and the auth token as the password. Assuming the login is *XXXXX* and the auth token is *YYYYY*:
```bash
# list products
curl -u XXXXX:YYYYY "https://api.jumpseller.com/v1/products.json"
# create a product
curl -u XXXXX:YYYYY -X POST "https://api.jumpseller.com/v1/products.json" \
-H "Content-Type: application/json" \
-d ''{ "product": { "name": "My new Product!", "price": 100 } }''
# update product 123
curl -u XXXXX:YYYYY -X PUT "https://api.jumpseller.com/v1/products/123.json" \
-H "Content-Type: application/json" \
-d ''{ "product": { "name": "My updated Product!", "price": 99 } }''
# delete product 123
curl -u XXXXX:YYYYY -X DELETE "https://api.jumpseller.com/v1/products/123.json"
```
The same product creation in PHP:
```php
$login = ''XXXXX'';
$authtoken = ''YYYYY'';
$ch = curl_init(''https://api.jumpseller.com/v1/products.json'');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, $login . '':'' . $authtoken);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(''Content-Type: application/json''));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, ''POST'');
curl_setopt($ch, CURLOPT_POSTFIELDS, ''{ "product": { "name": "My new Product!", "price": 100 } }'');
$result = curl_exec($ch);
curl_close($ch);
```
### Query parameters (deprecated)
The login and auth token can also be sent as the `login` and `authtoken` query parameters. URLs end up in server logs and browser history, so prefer Basic Authentication. ```bash
curl "https://api.jumpseller.com/v1/products.json?login=XXXXX&authtoken=YYYYY"
```
## OAuth 2.0
Jumpseller Apps authenticate with OAuth 2.0 using the **Authorization Code** flow. The merchant approves the access your app asks for, and your app receives a token for that store. | Endpoint | URL |
|----------|-----|
| Authorization | `https://accounts.jumpseller.com/oauth/authorize` |
| Token | `https://accounts.jumpseller.com/oauth/token` |
| Token info | `https://accounts.jumpseller.com/oauth/token/info` |
**1. Send the merchant to the authorization page**
```text
https://accounts.jumpseller.com/oauth/authorize
?client_id=YOUR_CLIENT_ID
&redirect_uri=https://yourapp.com/callback
&response_type=code
&scope=read_products write_orders
```
The merchant logs in and approves the access. Jumpseller redirects back to your `redirect_uri` with an authorization `code`, valid for 10 minutes. **2.'
version: 1.0.0
x-logo:
url: https://api.jumpseller.com/images/jumpseller-logo-full.svg
altText: Jumpseller logo
href: /
servers:
- url: https://api.jumpseller.com/v1
tags:
- name: Appointments
paths:
/products/{id}/appointment_timeslots.json:
get:
tags:
- Appointments
summary: Retrieve available appointment timeslots for a Product
description: Returns available timeslots per date for an appointment Product, taking capacity (including shared calendars and blocked dates for weekly recurring Products), and existing bookings into account. `start_date` and `end_date` are required and dates use the store timezone; the range is limited to 31 days, matching the storefront's own appointment widget. For weekly recurring Products, timeslots are generated from the weekly schedule. For `specific_dates` Products, the merchant-configured timeslots (got as in `GET /products/{id}.json`) are returned by key of `start_date` and annotated with remaining capacity; a slot may also include `end_date`/`end_time` when it spans multiple days.
security:
- BasicAuthentication:
- products
- loginParameter: []
authtokenParameter: []
- OAuth2:
- read_products
parameters:
- $ref: '#/components/parameters/ProductIDParam'
- name: start_date
in: query
required: true
description: Inclusive lower boundary of the date range to check.
schema:
type: string
format: date
example: '2026-08-26'
- name: end_date
in: query
required: true
description: Inclusive upper boundary of the date range to check. Limited to 31 days after `start_date`.
schema:
type: string
format: date
example: '2026-08-31'
responses:
'200':
description: A map of dates to their available timeslots.
content:
application/json:
schema:
$ref: '#/components/schemas/AppointmentTimeslotsByDate'
'400':
description: Invalid date range, or the Product is not an appointment Product.
content:
application/json:
schema:
$ref: '#/components/schemas/MessageObject'
'404':
description: Product Not Found.
content:
application/json:
schema:
$ref: '#/components/schemas/NotFound'
x-codeSamples:
- lang: Shell
label: cURL
source: curl -u XXXXX:YYYYY -X GET "https://api.jumpseller.com/v1/products/123/appointment_timeslots.json?start_date=2026-08-26&end_date=2026-08-31"
- lang: PHP
label: PHP
source: '<?php
$login = ''XXXXX'';
$authtoken = ''YYYYY'';
$url = ''https://api.jumpseller.com/v1/products/123/appointment_timeslots.json?start_date=2026-08-26&end_date=2026-08-31'';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, $login . '':'' . $authtoken);
curl_setopt($ch, CURLOPT_HTTPHEADER, [''Content-Type: application/json'']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;'
- lang: Ruby
label: Ruby
source: 'require ''net/http''
require ''json''
uri = URI(''https://api.jumpseller.com/v1/products/123/appointment_timeslots.json?start_date=2026-08-26&end_date=2026-08-31'')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request.basic_auth(''XXXXX'', ''YYYYY'')
request[''Content-Type''] = ''application/json''
response = http.request(request)
puts JSON.parse(response.body)'
- lang: Python
label: Python
source: "import requests\n\nresponse = requests.get(\n 'https://api.jumpseller.com/v1/products/123/appointment_timeslots.json',\n params={'start_date': '2026-08-26', 'end_date': '2026-08-31'},\n auth=('XXXXX', 'YYYYY')\n)\nprint(response.json())"
- lang: JavaScript
label: JavaScript
source: "const response = await fetch('https://api.jumpseller.com/v1/products/123/appointment_timeslots.json?start_date=2026-08-26&end_date=2026-08-31', {\n method: 'GET',\n headers: {\n 'Authorization': 'Basic ' + btoa('XXXXX:YYYYY'),\n 'Content-Type': 'application/json'\n }\n});\n\nconst data = await response.json();\nconsole.log(data);"
operationId: getProductsByIdAppointmentTimeslotsJson
x-operation-id-source: derived
/appointments.json:
get:
tags:
- Appointments
summary: Retrieve all Appointments
description: Returns store appointments, ordered by start date and time in descending order. Use `fields` to select response fields. `start_date` and `end_date` form an inclusive interval over the start date to filter appointments; either boundary may be used on its own. Dates and returned timeslots use the store timezone.
security:
- BasicAuthentication:
- orders
- loginParameter: []
authtokenParameter: []
- OAuth2:
- read_orders
parameters:
- $ref: '#/components/parameters/LimitParam'
- $ref: '#/components/parameters/PageParam'
- name: fields
in: query
description: Comma-separated appointment fields to include in each response.
schema:
type: string
example: id,status,timeslot
- name: status
in: query
description: Filter by appointment status. Use `requested` to list the booking requests waiting for your approval.
schema:
type: string
enum:
- created
- voided
- canceled
- pending
- booked
- completed
- requested
- accepted
- rejected
- expired
example: booked
- name: product_id
in: query
description: Filter by appointment product id.
schema:
type: integer
format: int32
- name: customer_id
in: query
description: Filter by customer id.
schema:
type: integer
format: int32
- name: start_date
in: query
description: Inclusive lower boundary for the appointment start date.
schema:
type: string
format: date
example: '2026-08-26'
- name: end_date
in: query
description: Inclusive upper boundary for the appointment start date.
schema:
type: string
format: date
example: '2026-08-31'
responses:
'200':
description: An array of appointments.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/AppointmentResponse'
'400':
description: Invalid date filter.
content:
application/json:
schema:
$ref: '#/components/schemas/MessageObject'
x-codeSamples:
- lang: Shell
label: cURL
source: curl -u XXXXX:YYYYY -X GET "https://api.jumpseller.com/v1/appointments.json?fields=id,status,timeslot&start_date=2026-08-26"
operationId: getAppointmentsJson
x-operation-id-source: derived
/appointments/{id}.json:
get:
tags:
- Appointments
summary: Retrieve an Appointment
description: Returns a single appointment by id. Use `fields` to select response fields.
security:
- BasicAuthentication:
- orders
- loginParameter: []
authtokenParameter: []
- OAuth2:
- read_orders
parameters:
- name: id
in: path
description: Id of the appointment.
required: true
schema:
type: integer
format: int32
- name: fields
in: query
description: Comma-separated appointment fields to include in the response.
schema:
type: string
example: id,status,timeslot
responses:
'200':
description: Appointment retrieved successfully.
content:
application/json:
schema:
$ref: '#/components/schemas/AppointmentResponse'
'404':
description: Appointment not found.
content:
application/json:
schema:
$ref: '#/components/schemas/NotFound'
x-codeSamples:
- lang: Shell
label: cURL
source: curl -u XXXXX:YYYYY -X GET "https://api.jumpseller.com/v1/appointments/12.json"
operationId: getAppointments{id}Json
x-operation-id-source: derived
put:
tags:
- Appointments
summary: Update an Appointment
description: 'Changes an appointment status, reschedules it, or performs both updates atomically. Rescheduling requires `start_time` and is only allowed when the resulting status is `booked`; `end_time` is optional and, when omitted, the appointment keeps its current duration. Times use the store timezone. The requested timeslot must belong to the product schedule and have available capacity. Changing the status to `booked` without rescheduling also checks that the appointment''s current timeslot still has available capacity. Allowed status transitions: `pending` to `booked` or `canceled`, `booked` to `completed` or `canceled`, and `canceled` or `completed` back to `booked`. To delete an appointment while preserving its order history, set `status` to `canceled`.'
security:
- BasicAuthentication:
- orders
- loginParameter: []
authtokenParameter: []
- OAuth2:
- write_orders
parameters:
- name: id
in: path
description: Id of the appointment.
required: true
schema:
type: integer
format: int32
- name: fields
in: query
description: Comma-separated appointment fields to include in the response.
schema:
type: string
example: id,status,timeslot
requestBody:
description: Appointment status and/or timeslot changes.
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/AppointmentEdit'
responses:
'200':
description: Appointment updated successfully.
content:
application/json:
schema:
$ref: '#/components/schemas/AppointmentResponse'
'400':
description: Unavailable timeslot or invalid status transition, or invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/MessageObject'
'404':
description: Appointment not found.
content:
application/json:
schema:
$ref: '#/components/schemas/NotFound'
x-codegen-request-body-name: body
x-codeSamples:
- lang: Shell
label: Reschedule
source: "curl -u XXXXX:YYYYY -X PUT \"https://api.jumpseller.com/v1/appointments/12.json\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\"appointment\": {\"start_time\": \"2026-08-26 18:49\", \"end_time\": \"2026-08-26 19:16\"}}'"
- lang: Shell
label: Change status and reschedule
source: "curl -u XXXXX:YYYYY -X PUT \"https://api.jumpseller.com/v1/appointments/12.json\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\"appointment\": {\"status\": \"booked\", \"start_time\": \"2026-08-26 18:01\", \"end_time\": \"2026-08-26 18:31\"}}'"
- lang: Shell
label: Cancel
source: "curl -u XXXXX:YYYYY -X PUT \"https://api.jumpseller.com/v1/appointments/12.json\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\"appointment\": {\"status\": \"canceled\"}}'"
operationId: putAppointments{id}Json
x-operation-id-source: derived
components:
parameters:
PageParam:
name: page
in: query
description: Page number, starting at 1.
schema:
type: integer
default: 1
minimum: 1
LimitParam:
name: limit
in: query
description: Number of objects per page (maximum 100).
schema:
type: integer
default: 50
minimum: 1
maximum: 100
ProductIDParam:
name: id
in: path
description: Id of the Product
required: true
schema:
type: integer
format: int32
schemas:
MessageObject:
type: object
properties:
message:
type: string
AppointmentTimeslotsByDate:
type: object
description: A map of `YYYY-MM-DD` date strings (the timeslot's `start_date`) to their available timeslots.
additionalProperties:
type: array
items:
type: object
properties:
start_time:
type: string
description: Timeslot start time in the store timezone.
example: '10:00'
end_date:
type: string
format: date
description: Timeslot end date in the store timezone. Only present for `specific_dates` Products, whose slots may span multiple days.
example: '2026-08-26'
end_time:
type: string
description: Timeslot end time in the store timezone.
example: '10:30'
capacity:
type:
- integer
- 'null'
format: int32
description: Maximum bookings allowed for this timeslot across any linked shared calendar products. `null` when the product has unlimited capacity.
example: 5
remaining:
type:
- integer
- 'null'
format: int32
description: Remaining bookable capacity for this timeslot. `null` when the product has unlimited capacity.
example: 3
existing_count:
type: integer
format: int32
description: Number of existing bookings already counted against this timeslot's capacity.
example: 2
example:
'2026-08-26':
- start_time: '10:00'
end_time: '10:30'
capacity: 5
remaining: 3
existing_count: 2
'2026-08-27': []
AppointmentTimeslot:
type: object
properties:
start_date:
type: string
format: date
description: Timeslot start date in the store timezone.
start_time:
type: string
description: Timeslot start time in the store timezone (HH:MM).
end_date:
type: string
format: date
description: Timeslot end date in the store timezone.
end_time:
type: string
description: Timeslot end time in the store timezone (HH:MM).
duration:
type: integer
description: Appointment duration in minutes.
timezone:
type: string
description: Store timezone in IANA timezone format, like `America/New_York`
Appointment:
type: object
properties:
id:
type: integer
description: Appointment unique identifier.
status:
type: string
description: 'Appointment status. `created` and `voided`: in a cart that wasn''t placed. `pending`: waiting for payment. `booked`: paid. `completed`: the appointment took place. `canceled`: canceled. For products that require approval: `requested` waits for your approval, `accepted` waits for the customer''s payment, `rejected` was rejected by you, `expired` wasn''t approved or paid in time.'
enum:
- created
- voided
- canceled
- pending
- booked
- completed
- requested
- accepted
- rejected
- expired
status_name:
type: string
description: Human-readable appointment status.
name:
type:
- string
- 'null'
description: Appointment name.
duration:
type: integer
description: Appointment duration in minutes.
store_timezone:
type: string
description: Store timezone in IANA timezone format, like `America/New_York`
timeslot:
$ref: '#/components/schemas/AppointmentTimeslot'
product_id:
type: integer
description: ID of the associated product.
product_name:
type: string
description: Name of the associated product.
customer_id:
type: integer
description: ID of the associated customer.
customer_name:
type: string
description: Name of the associated customer.
customer_email:
type: string
format: email
description: Email address of the customer.
order_product_id:
type: integer
description: ID of the associated order product.
order_id:
type: integer
description: ID of the associated order.
order_number:
type: integer
description: Order number.
created_at:
type: string
description: Appointment creation timestamp in UTC.
updated_at:
type: string
description: Appointment last update timestamp in UTC.
NotFound:
type: object
properties:
message:
type: string
AppointmentResponse:
type: object
properties:
appointment:
$ref: '#/components/schemas/Appointment'
AppointmentEdit:
type: object
properties:
appointment:
type: object
properties:
status:
type: string
description: 'Appointment status. `accepted` and `rejected` decide a booking request (status `requested`) for the whole order: accepting emails the customer a link to pay, rejecting cancels the order.'
enum:
- booked
- canceled
- completed
- accepted
- rejected
example: booked
start_time:
type: string
description: Appointment start date and time in the store timezone.
example: 2026-08-26 18:49
end_time:
type: string
description: Appointment end date and time in the store timezone.
example: 2026-08-26 19:16
securitySchemes:
BasicAuthentication:
type: http
scheme: basic
description: HTTP Basic authentication with your API login as the username and your auth token as the password. See [API credentials](#/section/authentication/api-credentials).
loginParameter:
type: apiKey
in: query
name: login
description: 'Deprecated: your API login as a query parameter. Use Basic authentication instead.'
authtokenParameter:
type: apiKey
in: query
name: authtoken
description: 'Deprecated: your API auth token as a query parameter. Use Basic authentication instead.'
OAuth2:
type: oauth2
description: OAuth 2.0 Authorization Code flow, for Jumpseller Apps. Access tokens expire after 1 hour and can be renewed with the refresh token. See [OAuth 2.0](#/section/authentication/oauth-2.0).
flows:
authorizationCode:
authorizationUrl: https://accounts.jumpseller.com/oauth/authorize
tokenUrl: https://accounts.jumpseller.com/oauth/token
refreshUrl: https://accounts.jumpseller.com/oauth/token
scopes:
read_apps: Read installed apps
read_categories: Read product categories
write_categories: Create, update, and delete categories
read_checkout_custom_fields: Read checkout additional fields
write_checkout_custom_fields: Update checkout additional fields
read_countries: Read country information
write_countries: Update country settings
read_custom_fields: Read product custom fields
write_custom_fields: Create and update custom fields
read_customer_categories: Read customer categories
write_customer_categories: Create and update customer categories
read_customers: Read customer accounts and groups
write_customers: Create, update, and delete customers
read_fulfillments: Read fulfillment information
write_fulfillments: Create and update fulfillments
read_hooks: Read webhooks
write_hooks: Create, update, and delete webhooks
read_jsapps: Read JavaScript apps
write_jsapps: Create, update, and delete JavaScript apps
read_locations: Read warehouse locations
write_locations: Create and update locations
read_orders: Read orders, fulfillments, and order history
write_orders: Create, update, and refund orders
read_pages: Read store pages
write_pages: Create, update, and delete pages
read_payment_methods: Read payment methods
write_payment_methods: Create and update payment methods
read_products: Read products, variants, images, options, and custom fields
write_products: Create, update, and delete products
read_promotions: Read promotions and discounts
write_promotions: Create, update, and delete promotions
write_reviews: Manage product reviews
read_settings: Read store configuration
write_settings: Update store configuration
read_shipping_methods: Read shipping methods and rates
write_shipping_methods: Create and update shipping methods
read_store: Read store information and settings
write_store: Update store settings
write_store_setup: Create new stores via the store setup endpoint
read_taxes: Read tax rules
write_taxes: Create and update tax rules