# List jobs in a date range

```http
POST https://secure.yoprint.com/v1/api/store/{team_slug}/job/calendar
```

- API version: v1
- Operation ID: `v1_public_job_calendar`
- Section: Production › [Jobs](https://developer.yoprint.com/reference/jobs.md)
- Web page: https://developer.yoprint.com/reference/jobs/v1-job-calendar/
- Authentication: `Authorization: Bearer YOUR_API_KEY`

Jobs whose start or due date falls in the range, or whose dates span it. Send `page` (an integer from 1) and optionally `per_page` (blank means 500, otherwise an integer from 1 to 1000) to read the range page by page: the response is that page of the whole range, uncapped, with `pagination`. Without `page`, or with a blank one, the response holds at most 1,200 rows and no `pagination`, and `per_page` is ignored. Any other `page` or `per_page` value is a 422 that names the field. Rows follow the requested sort, then id, so pages never overlap or skip.

The range runs from the start of the day of `start_date` to the end of the day of `end_date`. Send both as ISO 8601 date-times in UTC (`2026-11-01T00:00:00Z`): the day boundaries are taken from the date as written.

Each job is the full job with its tasks (`pipelines`), `mockup` and `production_file`; `services` and `pending_approval` are left out. Only jobs on sales orders are listed: quotes, drafts and deleted jobs are left out.

You can narrow the range with the same `filters` and `sort` as Filter jobs. A date filter's `value` is a whole number of days, counted from the moment of the request in UTC: `eq` N matches the whole UTC day N days from today (0 is today, -1 yesterday); `gte` N matches dates on or after now plus N days; `lte` N matches dates on or before now **minus** N days. So "due in the next 7 days" is `due_date gte 0` and `due_date lte -7`, and "overdue" is `due_date lte 0`. This differs from the v2 filters (Filter invoices, the production control calendar), where `lte` and `gte` both count forward.

## Permission

Any member of the team. No sales order permission is checked.

## Business rules

- `start_date` and `end_date` are required ISO 8601 dates.
- A job is in the range when its start date or its due date falls in it, or it starts before the range and is due after it. Undated jobs never appear.

## Path parameters

- `team_slug` (string, required): Your team slug, shown as Team ID next to your API key in Profile. Example `your-team`.

## Request body

Content type `application/json`, required.

Fields:

- `end_date` (string (date-time), required): The last day of the range (ISO 8601). The range ends at the end of this day.
- `start_date` (string (date-time), required): The first day of the range (ISO 8601). The range starts at the start of this day.
- `filters` (array of objects, optional): Conditions, all of which must match. Omit for no filter. At least 1 item.
  - Each item:
    - `key` (string, required): What to filter on. See the table in the description. One of: `"status_id"`, `"status_type"`, `"is_rush"`, `"start_date"`, `"due_date"`, `"start_date_is_set"`, `"due_date_is_set"`, `"need_cust_provide_product"`, `"job_has_pipelines"`, `"has_any_pipelines"`, `"status_last_change_date"`, `"status_completion_date"`, `"total_qty_need_ordering"`, `"order_created_by"`, `"search"`.
    - `operator` (string, required): How to compare. Each kind of key accepts only some operators. One of: `"eq"`, `"neq"`, `"gt"`, `"gte"`, `"lt"`, `"lte"`, `"in"`, `"nin"`, `"bt"`, `"ct"`, `"sw"`, `"ew"`.
    - `value` (string | number | boolean | array, required): What to compare with: text, a number of days, true or false, or an array of hash ids or options, by kind of key.
- `page` (integer, optional): Read the range page by page. Without it, at most 1,200 jobs come back and no `pagination`. Minimum 1.
- `per_page` (integer | null, optional): Page size when `page` is sent. Ignored without `page`. Default `500`. Minimum 1. Maximum 1000.
- `sort` (array of objects, optional): Sort keys, applied in order, then by job id. Without `sort` the jobs come by job id.
  - Each item:
    - `direction` (string, required): One of: `"asc"`, `"desc"`.
    - `key` (string, required): One of: `"id"`, `"due_date"`, `"order_id"`, `"status_id"`, `"start_date"`, `"impression_count"`, `"item_count"`, `"scoped_id"`, `"is_rush"`, `"position"`, `"status_last_change_date"`, `"status_completion_date"`, `"order_due_date"`, `"order_ship_due_date"`, `"order_cust_due_date"`, `"order_issue_date"`, `"total_qty_need_ordering"`, `"order_ship_due_date_undated_last"`, `"created_at_id"`.

### Example request

```bash
curl -X POST 'https://secure.yoprint.com/v1/api/store/your-team/job/calendar' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Accept: application/json' \
  -H 'X-Yoprint-Decimal-Format: exact-v1' \
  -H 'Content-Type: application/json' \
  -d '{
    "end_date": "2026-11-30T00:00:00Z",
    "filters": [
      {
        "key": "status_type",
        "operator": "nin",
        "value": [
          "end"
        ]
      }
    ],
    "page": 1,
    "per_page": 500,
    "start_date": "2026-11-01T00:00:00Z"
  }'
```

## Response

`200` Successful response.

Fields:

- `data` (array of objects, required)
  - Each item:
    - `approval_ready_mockup_design_count` (integer, optional)
    - `assigned_users` (array of objects, optional): People on the job.
      - Each item:
        - `avatar_url` (string | null, optional)
        - `id` (string, optional): The user.
        - `name` (string, optional)
    - `auto_saved_for` (string | null, optional): Set only on autosave copies.
    - `customer` (object, optional)
      - `id` (string | null, optional): The customer.
      - `name` (string | null, optional)
    - `due_date` (string (date-time) | null, optional): Production due date. ISO 8601 with offset, or null.
    - `from_legacy` (boolean, optional)
    - `has_service` (boolean, optional): Kept for older clients; not a count of services.
    - `id` (string, optional): The job.
    - `impression_count` (number | null, optional)
    - `inventory_status` (string | null, optional): The stock status of the job's lines.
    - `is_rush` (boolean, optional)
    - `item_count` (number | null, optional): Units on the job.
    - `location_count` (number | null, optional)
    - `mockup` (array of objects, optional): Mockup files.
      - Each item:
        - `id` (string, optional): The file.
        - `name` (string | null, optional)
        - `url` (string | null, optional): Download link with its own access token.
    - `mockup_design_count` (integer, optional)
    - `mockup_summary` (object, optional)
      - `count` (integer, optional)
      - `has_mockups` (boolean, optional)
    - `name` (string | null, optional)
    - `need_cust_provide_product` (boolean | integer | null, optional): Blanks are provided by the customer.
    - `note` (string | null, optional)
    - `order_customer_po_number` (string | null, optional)
    - `order_id` (string, optional): The order.
    - `order_scoped_id` (string, optional): The order number.
    - `pdf` (array of objects, optional): PDF links.
      - Each item:
        - `label` (string, optional)
        - `url` (string (uri), optional): A download link that carries its own long-lived access token: don't publish it.
    - `pipelines` (array of objects, optional): The job's tasks.
      - Each item:
        - `assigned_users` (array of objects, optional): Who is assigned. Same fields as `data[].assigned_users` above.
        - `created_at` (string (date-time), optional)
        - `due_date` (string (date-time) | null, optional): Task due date. ISO 8601 with offset, or null.
        - `id` (string, optional): The task.
        - `job_id` (string, optional): The job.
        - `job_is_rush` (boolean | integer | null, optional)
        - `job_item_count` (number | null, optional)
        - `job_name` (string | null, optional)
        - `job_scoped_id` (string, optional): The job number with its prefix.
        - `job_status_id` (string | null, optional): The job's current status.
        - `name` (string, optional)
        - `note` (string | null, optional)
        - `order_id` (string, optional): The order.
        - `order_name` (string | null, optional)
        - `order_scoped_id` (string | null, optional): The order number.
        - `pipeline_id` (string, optional): The task preset it comes from.
        - `position` (integer, optional): Order among tasks; lower comes first. 0 when unset.
        - `sales_order` (object, optional): A summary of the job's order.
          - `created_by` (string | null, optional): Who created the order.
          - `cust_due_date` (string (date-time) | null, optional): Order customer due (in-hand) date. ISO 8601 with offset, or null.
          - `customer_id` (string | null, optional): The customer.
          - `customer_name` (string | null, optional)
          - `due_date` (string (date-time) | null, optional): Order production due date. ISO 8601 with offset, or null.
          - `external_type` (string | null, optional): `shopify` when the order came from Shopify, else null.
          - `is_quote` (boolean, optional)
          - `issue_date` (string (date-time) | null, optional): Order issue date. ISO 8601 with offset, or null.
          - `object_type` (string | null, optional): `sales_order` or `quote`.
          - `ship_due_date` (string (date-time) | null, optional): Order ship-by date. ISO 8601 with offset, or null.
          - `shopify_deleted_externally` (boolean, optional)
          - `shopify_deleted_externally_at` (string (date-time) | null, optional): When it was deleted in Shopify. ISO 8601 with offset, or null.
          - `start_date` (string (date-time) | null, optional): Order production start. ISO 8601 with offset, or null.
          - `status_id` (string | null, optional): The order status.
        - `start_date` (string (date-time) | null, optional): Task start. ISO 8601 with offset, or null.
        - `status` (object, optional): A status: label, kind and place in the list.
          - `color` (string | null, optional): Hex color.
          - `customer_label` (string, optional)
          - `id` (string, optional): The status.
          - `label` (string, optional)
          - `pipeline_id` (string, optional): Only on the statuses of a task preset (`role` `pipeline`): the task preset. Absent on other statuses.
          - `position` (integer, optional): Its place in the team's list: sort by it to find the next status.
          - `role` (string, optional): Which list it belongs to: `job` for job statuses, `pipeline` for the statuses of a task preset. One of: `"order"`, `"quote"`, `"job"`, `"purchase_order"`, `"shipment"`, `"customer_message"`, `"pipeline"`.
          - `trashed` (boolean, optional): The status was deleted.
          - `type` (string, optional): The kind of status: `start` (Pending), `pre_production` and `in_progress` (In Progress), `end` (Completed). One of: `"start"`, `"pre_production"`, `"in_progress"`, `"end"`.
        - `status_completion_date` (string (date-time) | null, optional): When it reached a Completed status. ISO 8601 with offset, or null.
        - `status_id` (string, optional): The task's status (a status of its task preset).
        - `status_last_change_date` (string (date-time) | null, optional): When the status last changed. ISO 8601 with offset, or null.
        - `updated_at` (string (date-time), optional)
    - `position` (integer | null, optional)
    - `pricing_original_total` (decimal pair, optional): The job's price before pricing rules, at the stored scale. A decimal pair: the amount is `value` ÷ 10^`dp` (`{ "value": 1250, "dp": 2 }` is 12.50). Read `dp` every time: it can differ between fields and records. See https://developer.yoprint.com/concepts/money-and-quantities.md.
    - `pricing_rule_applied` (object | null, optional): The pricing rule that set the job's decoration price, or null. These answers usually carry only `type`, the two ids and the two totals. List the jobs of a sales order or quote and Get one job of a sales order or quote answer with the full summary (the rule's current name and position, the prices before and after).
      - `after` (string | null, optional): Full summary only: the price after the rule, as a decimal string.
      - `after_total` (decimal pair, optional): The decoration price after the rule. A decimal pair: the amount is `value` ÷ 10^`dp` (`{ "value": 1250, "dp": 2 }` is 12.50). Read `dp` every time: it can differ between fields and records. See https://developer.yoprint.com/concepts/money-and-quantities.md.
      - `base` (string | null, optional): Full summary only: the decoration price the rule started from, as a decimal string.
      - `base_type` (string | null, optional): Full summary only: `service_price`.
      - `normal_price` (string | null, optional): Full summary only: the price with no rule (the same as `base` for a job).
      - `original_total` (decimal pair, optional): The decoration price before the rule. A decimal pair: the amount is `value` ÷ 10^`dp` (`{ "value": 1250, "dp": 2 }` is 12.50). Read `dp` every time: it can differ between fields and records. See https://developer.yoprint.com/concepts/money-and-quantities.md.
      - `pricing_group_id` (string | null, optional): The pricing group.
      - `pricing_group_name` (string | null, optional): Full summary only: the group's name now.
      - `pricing_group_removed` (boolean | null, optional): Full summary only: true when the group was removed since. The job keeps its price.
      - `pricing_rule_id` (string | null, optional): The pricing rule.
      - `rule` (object | null, optional): Full summary only: the rule as the group holds it now (`id`, `label`, `position`, where 1 is the first rule checked), or null when it no longer exists.
      - `type` (string | null, optional): `service` on a job.
    - `pricing_total` (decimal pair, optional): The job's price, at the stored scale (usually 6 decimal places: `{ "value": 600000000, "dp": 6 }` is 600.00). A decimal pair: the amount is `value` ÷ 10^`dp` (`{ "value": 1250, "dp": 2 }` is 12.50). Read `dp` every time: it can differ between fields and records. See https://developer.yoprint.com/concepts/money-and-quantities.md.
    - `production_file` (array of objects, optional): Production files. Same fields as `data[].mockup` above.
    - `qr_code_url` (string | null, optional): A QR code image for the job.
    - `sales_order` (object, optional): A summary of the job's order.
      - `created_by` (string | null, optional): Who created the order.
      - `cust_due_date` (string (date-time) | null, optional): Order customer due (in-hand) date. ISO 8601 with offset, or null.
      - `due_date` (string (date-time) | null, optional): Order production due date. ISO 8601 with offset, or null.
      - `external_type` (string | null, optional): `shopify` when the order came from Shopify, else null.
      - `is_quote` (boolean, optional)
      - `is_rush` (boolean, optional)
      - `issue_date` (string (date-time) | null, optional): Order issue date. ISO 8601 with offset, or null.
      - `name` (string | null, optional): Order name.
      - `object_type` (string | null, optional): `sales_order` or `quote`.
      - `ship_due_date` (string (date-time) | null, optional): Order ship-by date. ISO 8601 with offset, or null.
      - `shopify_deleted_externally` (boolean, optional)
      - `shopify_deleted_externally_at` (string (date-time) | null, optional): When it was deleted in Shopify. ISO 8601 with offset, or null.
      - `start_date` (string (date-time) | null, optional): Order production start. ISO 8601 with offset, or null.
      - `status_id` (string | null, optional): The order status.
    - `scoped_id` (string, optional): The job number as shown, with its `JOB-` prefix. Change a job number takes only the digits.
    - `services_still_valid` (boolean, optional)
    - `start_date` (string (date-time) | null, optional): Production start. ISO 8601 with offset, or null.
    - `status` (object, optional): A status: label, kind and place in the list. Same fields as `data[].pipelines[].status` above.
    - `status_completion_date` (string (date-time) | null, optional): When it reached a Completed status. ISO 8601 with offset, or null.
    - `status_id` (string, optional): The job's current status: its production stage. Look it up in List job statuses, or read `status`.
    - `status_last_change_date` (string (date-time) | null, optional): When the status last changed. ISO 8601 with offset, or null.
    - `total_qty_need_ordering` (string | null, optional): Quantity that still needs ordering, with 8 decimal places (`"12.00000000"`). A decimal string, such as `"0.00000000"`; parse it as a decimal.
    - `unique_key` (string | null, optional): The job's unique key.
    - `version` (integer, optional)
- `status` (integer, required)
- `success` (boolean, required)
- `pagination` (object, optional)
  - `count` (integer, required)
  - `currentPage` (integer, required)
  - `links` (object | array of any, required): Links to the neighbouring pages: `previous` and `next`, each present only when that page exists. An empty list, `[]`, when there is only one page.
    - `next` (string (uri), optional): The next page.
    - `previous` (string (uri), optional): The previous page.
  - `perPage` (integer, required)
  - `total` (integer, required)
  - `totalPages` (integer, required)

Example response:

```json
{
  "data": [
    {
      "assigned_users": [],
      "auto_saved_for": null,
      "customer": {
        "id": "ifAHmADekGZ6id",
        "name": "Northwind Apparel"
      },
      "due_date": "2026-11-06T17:00:00+00:00",
      "id": "WaGvtaWsx7Kcn4",
      "is_rush": true,
      "item_count": 48,
      "mockup": [],
      "name": "Front print",
      "note": null,
      "order_id": "sFbALVSYD55eXe",
      "order_scoped_id": "SO1001",
      "pdf": [
        {
          "description": "Job details without mockup",
          "label": "Job Details",
          "url": "https://example.com/pdf/job-details.pdf"
        }
      ],
      "pipelines": [
        {
          "assigned_users": [
            {
              "avatar_url": null,
              "id": "4mdDkMg3dgQOa3",
              "name": "Alex Rivera"
            }
          ],
          "created_at": "2026-11-03T15:00:00+00:00",
          "due_date": "2026-11-05T17:00:00+00:00",
          "id": "hpioY1gDBQZdbI",
          "job_id": "WaGvtaWsx7Kcn4",
          "job_is_rush": 1,
          "job_item_count": 48,
          "job_name": "Front print",
          "job_scoped_id": "JOB-2419",
          "job_status_id": "scaWHQnPLtqMPT",
          "name": "Burn screens",
          "note": null,
          "order_id": "sFbALVSYD55eXe",
          "order_name": "Team shirts",
          "order_scoped_id": "SO1001",
          "pipeline_id": "SE3SfXjt6dPfnH",
          "position": 1,
          "sales_order": {
            "customer_id": "ifAHmADekGZ6id",
            "customer_name": "Northwind Apparel",
            "is_quote": false,
            "object_type": "sales_order",
            "status_id": "wgbOT87gGZvhgy"
          },
          "start_date": "2026-11-04T09:00:00+00:00",
          "status": {
            "color": "#2196f3",
            "customer_label": "In Progress",
            "id": "hTFITko5Q0R83y",
            "label": "Burning",
            "pipeline_id": "SE3SfXjt6dPfnH",
            "position": 2,
            "role": "pipeline",
            "trashed": false,
            "type": "in_progress"
          },
          "status_completion_date": null,
          "status_id": "hTFITko5Q0R83y",
          "status_last_change_date": "2026-11-03T15:05:00+00:00",
          "updated_at": "2026-11-03T15:05:00+00:00"
        }
      ],
      "position": 1,
      "pricing_original_total": {
        "dp": 6,
        "value": 600000000
      },
      "pricing_rule_applied": null,
      "pricing_total": {
        "dp": 6,
        "value": 600000000
      },
      "production_file": [],
      "sales_order": {
        "is_quote": false,
        "is_rush": false,
        "name": "Team shirts",
        "object_type": "sales_order",
        "status_id": "wgbOT87gGZvhgy"
      },
      "scoped_id": "JOB-2419",
      "start_date": "2026-11-04T09:00:00+00:00",
      "status": {
        "color": "#2196f3",
        "customer_label": "In Progress",
        "id": "scaWHQnPLtqMPT",
        "label": "Printing",
        "position": 3,
        "role": "job",
        "trashed": false,
        "type": "in_progress"
      },
      "status_completion_date": null,
      "status_id": "scaWHQnPLtqMPT",
      "status_last_change_date": "2026-11-03T15:05:00+00:00",
      "total_qty_need_ordering": "0.00000000",
      "unique_key": "job_EXAMPLEuniqueKey"
    }
  ],
  "pagination": {
    "count": 1,
    "currentPage": 1,
    "links": [],
    "perPage": 500,
    "total": 1,
    "totalPages": 1
  },
  "status": 200,
  "success": true
}
```

## Errors

- `401` The API key is missing or wrong (`unauthenticated`).
- `403` You are not allowed to do this. `api_access_not_in_plan`: your team's plan doesn't include API access (Pro and above, with an active subscription or trial), so every request answers this until the team upgrades. When your role lacks the permission the operation needs, the body is only `{"message": "Insufficient Permission"}`. Other refusals use the error envelope, with `unauthorized` or `user_is_not_authorized`.
- `404` Not found. `page_not_found`: the team slug is unknown, you are not a member of the team, or an id in the path is not one of this team's. `code: null`, with a message that starts "No query results for": there is no record with that id.
- `422` The request was refused and changed nothing. `validation_failed` lists what to fix in `error.fields`; other codes name a business rule, explained in `error.message`. A few checks answer with only `{"message": "..."}`. An operation that calls another service (a payment provider, a carrier, an accounting app) can answer `connect_timeout` ("Please retry again") when that service does not answer in time: the change may or may not have happened there, so read the record back before you retry.
  - When: A date is missing or not ISO 8601; `page` is filled but not an integer from 1; `per_page` is outside 1 to 1000; or a filter is invalid. Fix: Send ISO 8601 dates and valid paging and filters. The error names the field.

## Notes

- Without `page` you get the first 1,200 jobs of the range in the order you asked for (by id when you send no `sort`). A busy range can hold more: send `page` and read until `pagination.currentPage` equals `pagination.totalPages`.

## Related

- [Filter jobs](https://developer.yoprint.com/reference/jobs/v1-job-filter.md): `POST /v1/api/store/{team_slug}/job/filter`
- [List tasks in a date range](https://developer.yoprint.com/reference/tasks/v1-work-pipeline-calendar.md): `POST /v1/api/store/{team_slug}/work_pipeline/calendar`
- [Read the production control calendar](https://developer.yoprint.com/reference/production-control/v1-production-control-filter.md): `POST /v1/api/store/{team_slug}/production_control/filter`
