PlanRadar Tickets V2 API

All operations on PlanRadar tickets

Operations 25

GET /api/v2/{customer_id}/projects/{project_id}/tickets/journals Retrieve journals for all accessible tickets in a project
GET /api/v2/{customer_id}/projects/{project_id}/tickets Returns all tickets
POST /api/v2/{customer_id}/projects/{project_id}/tickets Creates ticket
GET /api/v2/{customer_id}/projects/{project_id}/tickets/tickets_position Returns tickets positions
POST /api/v2/{customer_id}/projects/{project_id}/tickets/export/xls Exports filtered tickets as Excel file
GET /api/v2/{customer_id}/projects/{project_id}/tickets/{uuid}/single_ticket_export Exports specific ticket
GET /api/v2/{customer_id}/projects/{project_id}/tickets/{uuid} Returns specific ticket
DELETE /api/v2/{customer_id}/projects/{project_id}/tickets/{uuid} Deletes specific ticket
PUT /api/v2/{customer_id}/projects/{project_id}/tickets/{uuid} Updates specific ticket
GET /api/v2/{customer_id}/projects/{project_id}/tickets/{uuid}/mark_as_seen Marks specific ticket as seen
POST /api/v2/{customer_id}/projects/{project_id}/tickets/export/pdf Exports filtered tickets as PDF
GET /api/v2/{customer_id}/projects/{project_id}/tickets/load_recurring_reminders Returns all recurring reminders
GET /api/v2/{customer_id}/projects/{project_id}/tickets/ticket_types_stats Returns the count of tickets per ticket type
PUT /api/v2/{customer_id}/projects/{project_id}/tickets/batch_update Updates multiple tickets at once
PUT /api/v2/{customer_id}/projects/{project_id}/tickets/multi_update Updates multiple tickets with array
POST /api/v2/{customer_id}/projects/{project_id}/tickets/batch_delete Deletes multiple tickets at once
POST /api/v2/{customer_id}/projects/{project_id}/tickets/batch_duplicate Duplicates multiple tickets at once
POST /api/v2/{customer_id}/projects/{project_id}/tickets/bulk_create Creates multiple tickets at once
GET /api/v2/{customer_id}/projects/{project_id}/tickets/bulk_create_status Returns the status of a bulk create job
GET /api/v2/{customer_id}/projects/{project_id}/tickets/{uuid}/journals Returns all journals of a ticket
POST /api/v2/{customer_id}/projects/{project_id}/tickets/{uuid}/comment Adds a comment to a specific ticket
GET /api/v2/{customer_id}/projects/{project_id}/tickets/{uuid}/subtickets Returns subtickets of a specific ticket
GET /api/v2/{customer_id}/projects/{project_id}/tickets/{uuid}/recurring_reminder_details Returns the recurring reminder of a ticket
GET /api/v2/{customer_id}/projects/{project_id}/tickets/{uuid}/gantt_task Returns the gantt task of a ticket
POST /api/v2/{customer_id}/projects/{project_id}/tickets/{uuid}/recurring_reminders Creates or updates a recurring reminder of a ticket

Work with this as data

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/planradar-tickets-v2-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 Specification

planradar-tickets-v2-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: PlanRadar's API Documentation Approval Requests V2 Tickets V2 API
  version: '2.0'
  description: "Welcome to PlanRadar's API documentation, here you can find all the details about our APIs as well as test them online.<br />\n        <h5>Rate Limits</h5>30 requests per minute per account, aggregated across all tokens.<br />\n        If the threshold is exceeded, a 5-minute cooldown is applied to the account, aggregated across all tokens.<br />\n        During the cooldown period, further requests may be rejected until the cooldown ends.<br />\n        In rare cases, an endpoint may have a different rate limit than the default. When that happens, the differing limit will be explicitly stated in the API documentation for that endpoint.<br />\n        <h5>Access Key</h5>In order to be able to access any API you have to create an access token.Therefore you have to follow these steps:-\n        <ul>\n          <li>Go to your profile page and click on Personal Access Tokens on the left side bar</li><li>Click on the 'Create Access Token' top right button in order to create a new access token.</li><li>Copy the created token and paste it into the field that pops up when you click on the 'Authorize' button </li><li>Note: you can copy the token only once.</li><li>Now you can easily access any API</li>\n        </ul>\n        <h5>V2 APIs</h5>We are currently working on upgrading all our APIs to v2, and we recommend that you use v2 APIs if it is available.\n        <p>V2 APIs are faster, robust and more flexible than v1 APIs</p>"
servers:
- url: /
tags:
- name: Tickets V2
  description: All operations on PlanRadar tickets
paths:
  /api/v2/{customer_id}/projects/{project_id}/tickets/journals:
    get:
      summary: Retrieve journals for all accessible tickets in a project
      tags:
      - Tickets V2
      description: 'Retrieve journal entries for every ticket the caller can access within the given project,

        in a single API call. Intended to replace individual `GET /tickets/{uuid}/journals` calls

        during ERP sync integrations.


        Counts as **1 API call**. Only returns journals from tickets the user has access to within

        the specified project. Field-level and document permissions are respected. Each journal

        entry includes `ticket-uuid` for mapping back to its ticket.


        **Pagination:** default 50, max 100 (server-enforced). Results ordered chronologically.


        **Typical sync flow:**

        1. `GET /tickets/journals?last_sync_date=...` with the timestamp from your last sync (this endpoint)

        2. Process changes, store new sync timestamp

        '
      security:
      - apiKey: []
      parameters:
      - name: customer_id
        in: path
        required: true
        description: Encoded customer ID
        example: ymjxnx
        schema:
          type: string
      - name: project_id
        in: path
        required: true
        description: Encoded project ID
        example: xqwprl
        schema:
          type: string
      - name: last_sync_date
        in: query
        required: false
        description: ISO 8601 datetime. Only return journal entries created on or after this datetime. Use for incremental sync — pass the timestamp from your last successful sync.
        example: '2026-03-20T10:15:00Z'
        schema:
          type: string
      - name: prop_keys
        in: query
        required: false
        description: Comma-separated list of journal_details.prop_key values to filter by (e.g. status_id, assigned_to_id). When provided, only journals with a matching detail row are returned.
        style: form
        explode: false
        schema:
          type: array
          items:
            type: string
      - name: page
        in: query
        required: false
        description: Page number (1-based). Defaults to 1.
        example: 1
        schema:
          type: integer
      - name: pagesize
        in: query
        required: false
        description: 'Number of journal entries per page. Default: 50. Maximum: 100 (server-enforced, values above 100 are clamped).'
        example: 50
        schema:
          type: integer
      responses:
        '200':
          description: Paginated — page and pagesize control the window
        '401':
          description: Unauthorized — missing or invalid API key
        '404':
          description: Caller is not a member of the project
  /api/v2/{customer_id}/projects/{project_id}/tickets:
    get:
      summary: Returns all tickets
      tags:
      - Tickets V2
      description: "This API returns all tickets of a specific project. <br />\n      Without any extra parameters it will return the first 100 tickets ordered by ascending ID. Extra parameters can be added to filter and sort the results.<br />\n      <b>Ticket Sorting:</b>\n      Tickets can be sorted by their attributes like component_id, priority_id etc. .\n      The sort is always ascending unless the field name is prefixed with a minus (U+002D HYPHEN-MINUS, “-“) i.e. `-id` or `id`.\n      <br /><b>Example: </b> `/tickets?sort=-component_id`<br />\n      <b>Ticket Filtring:</b>\n      You can use one of your created filters by providing its id to the `apply_filter` parameter. Moreover, you can use the on-fly filters.<br />\n      <b>On-Fly Filters:</b>\n      You can filter tickets based on the value of any of their attributes using structured filter parameters. Both simple and advanced formats are supported.<br />\n      <b>Simple Format:</b> `filter[{field}]={value}` - Direct field-value filtering<br />\n      <b>Advanced Format:</b> `filter[{field}][][predicate]={predicate}&filter[{field}][][value][]={value}` - Complex filtering with predicates<br />\n      <b>Simple Format Examples:</b><br />\n      • Filter by status: `/tickets?filter[status_id]=1` (Open tickets)<br />\n      • Filter by priority: `/tickets?filter[priority_id]=3` (High priority)<br />\n      • Multiple simple filters: `/tickets?filter[status_id]=1&filter[priority_id]=3`<br />\n      <b>Advanced Format Examples:</b><br />\n      • Filter by status with 'in' predicate: `/tickets?filter[status_id][][predicate]=in&filter[status_id][][value][]=1&filter[status_id][][value][]=2`<br />\n      • Filter by multiple conditions: `/tickets?filter[status_id][][predicate]=in&filter[status_id][][value][]=1&filter[priority_id][][predicate]=eq&filter[priority_id][][value][]=3`<br />\n      • Text search with 'like': `/tickets?filter[subject][][predicate]=like&filter[subject][][value][]=urgent`<br />\n      • Date range filtering: `/tickets?filter[created_at][][predicate]=between&filter[created_at][][value][]=2024-01-01&filter[created_at][][value][]=2024-12-31`<br />\n      <b>Available Predicates:</b> eq, neq, in, not_in, like, not_like, between, has, has_not, le, ge<br/>\n      <b>Image Loading:</b>\n      You can set load_images to true if you want the images of a ticket to be returned as well<br />\n      <b>Status Dictionary:</b> [1 (lm)= Open, 2 (ol) = In-Progress, 3 (ma) = Resolved, 4 (ex) = Feedback, 5 (gk) = Closed, 6 (ky) = Rejected]\n      <b>Priority Dictionary:</b> [1 = Low, 2 = Normal, 3 = High]\n\n      "
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
      - name: project_id
        in: path
        required: true
        description: Set project_id to `0` if you want to load the tickets of all projects
        schema:
          type: string
      - name: page
        in: query
        description: sets the number of pages for the returned tickets
        schema:
          type: integer
      - name: pagesize
        in: query
        description: sets the number of tickets that should be returned per page <br/>Maximum is 500, default is 100
        schema:
          type: integer
      - name: last_sync_date
        in: query
        description: is a Unix Timestamp. If it is set, only tickets that were created after that timestamp will be returned
        schema:
          type: string
      - name: sort
        in: query
        schema:
          type: string
      - name: filter[status_id]
        in: query
        description: "Simple status ID filter. Use status codes: 1=Open, 2=In-Progress, 3=Resolved, 4=Feedback, 5=Closed, 6=Rejected. Example: filter[status_id]=1 - Structured filter parameter supporting multiple conditions and predicates. You can use either simple or advanced format.<br/>\n      <b>Status ID Mapping:</b> 1 (lm)=Open, 2 (ol)=In-Progress, 3 (ma)=Resolved, 4 (ex)=Feedback, 5 (gk)=Closed, 6 (ky)=Rejected<br/>\n      <b>Simple Format:</b> filter[{field}]={value} - Example: filter[status_id]=1<br/>\n      <b>Advanced Format:</b> filter[{field}][][predicate]={predicate}&filter[{field}][][value][]={value}<br/>\n      <b>Supported Fields:</b> status_id, priority-id, assigned-to-id, author-id, subject, created-at, due-date, etc.<br/>\n      <b>Predicates:</b> eq (equals), neq (not equals), in (in list), not_in (not in list), like (contains), not_like (not contains), between (range), has (has value), has_not (no value), le (less/equal), ge (greater/equal)<br/>\n      <b>Examples:</b><br/>\n      • Simple: filter[status_id]=1 for filtering tickets with status 1<br/>\n      • Advanced: filter[status_id][][predicate]=in&filter[status_id][][value][]=1&filter[status_id][][value][]=2 for filtering tickets with status 1 or 2"
        schema:
          type: string
      - name: apply_filter
        in: query
        schema:
          type: string
      - name: load_images
        in: query
        description: sets whether or not the images of a ticket should be returned
        schema:
          type: boolean
      - name: can_have_parent
        in: query
        description: load only ticket that could have parent
        schema:
          type: boolean
      - name: search
        in: query
        description: keyword, based on which the tickets will be filtered
        schema:
          type: string
      responses:
        '406':
          description: Unsupported Accept Header
    post:
      summary: Creates ticket
      tags:
      - Tickets V2
      description: "This API is used for creating a ticket.<br/>\n      <b>customer-id</b>: Can be set to null in the request body to create a ticket without a customer association (used for form field attachment pre-upload tickets).<br/>\n      The response includes <b>typed_values_metadata</b> which contains metadata about form field attachments (e.g. has_attachments per field_id).<br/><br/>\n      <b>Note:</b> Do not modify the <code>meta-options</code> attribute - it is reserved for internal use.\n      <br /><br />\n      <b>Ticket Example:</b>\n      <br />\n      <pre>\n      {\n        \"data\": {\n          \"attributes\": {\n            \"uuid\": \"35b03889-e759-4ded-b848-24337eea10d2\",\n            \"subject\": \"After the Banality Post-Painterly Art of Misfortune\",\n            \"typed-values\": {\n              \"tf37e04757dabbca63\": 33.52511960017461,\n              \"tf601be06c9a1c46f7\": \"1989-06-05T23:16:06.412+00:00\",\n              \"tfd4367f50e84a9408\": \"Arbitrary Sustainability Daring to Defy Dysfunction\"\n            },\n            \"assigned-to-id\": \"gpk\",\n            \"status-id\": \"ma\",\n            \"component-id\": \"nyk\",\n            \"ticket-type-id\": \"obk\",\n            \"customer-id\": \"ymjxnx\"\n          }\n        }\n      }\n      </pre>"
      security:
      - apiKey: []
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
      - name: project_id
        in: path
        required: true
        schema:
          type: string
      responses:
        '404':
          description: Ticket Not Created
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  type: object
                  properties:
                    attributes:
                      $ref: '#/components/schemas/Ticket'
  /api/v2/{customer_id}/projects/{project_id}/tickets/tickets_position:
    get:
      summary: Returns tickets positions
      tags:
      - Tickets V2
      description: This API returns all tickets positions of a specific project without pagination.
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
      - name: project_id
        in: path
        required: true
        schema:
          type: string
      responses:
        '406':
          description: Unsupported Accept Header
  /api/v2/{customer_id}/projects/{project_id}/tickets/export/xls:
    post:
      summary: Exports filtered tickets as Excel file
      tags:
      - Tickets V2
      description: ' This API is used for exporting tickets as an Excel file based on their filter '
      security:
      - apiKey: []
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
      - name: project_id
        in: path
        required: true
        schema:
          type: string
      - name: pagesize
        in: query
        description: Maximum is 500, default is 100
        schema:
          type: integer
      - name: last_sync_date
        in: query
        schema:
          type: string
      - name: sort
        in: query
        schema:
          type: string
      - name: filter
        in: query
        schema:
          type: string
      - name: apply_filter
        in: query
        description: filterid, based on which the tickets should be filtered
        schema:
          type: string
      - name: search
        in: query
        description: keyword, based on which the tickets should be filtered
        schema:
          type: string
      - name: async
        in: query
        description: Set to true to force asynchronous (background) processing. When enabled, the response returns a job ID instead of the file directly.
        schema:
          type: boolean
      responses:
        '406':
          description: Unsupported Accept Header
  /api/v2/{customer_id}/projects/{project_id}/tickets/{uuid}/single_ticket_export:
    get:
      summary: Exports specific ticket
      tags:
      - Tickets V2
      description: This API is used for exporting a specific ticket based on its uuid.
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
      - name: project_id
        in: path
        required: true
        schema:
          type: string
      - name: uuid
        in: path
        description: unique identifier of the ticket
        required: true
        schema:
          type: string
      - name: pagesize
        in: query
        description: Maximum is 500, default is 100
        schema:
          type: integer
      - name: last_sync_date
        in: query
        schema:
          type: string
      - name: timezone_offset
        in: query
        description: ' -timestamp, is the difference between local time and the worlwide UTC time '
        schema:
          type: integer
      - name: async
        in: query
        description: Set to true to force asynchronous (background) processing. When enabled, the response returns a job ID instead of the file directly.
        schema:
          type: boolean
      responses:
        '406':
          description: Unsupported Accept Header
  /api/v2/{customer_id}/projects/{project_id}/tickets/{uuid}:
    get:
      summary: Returns specific ticket
      description: "This API returns a specific ticket based on its uuid.<br/>\n      The response includes a <b>typed_values_metadata</b> attribute, which is a JSON object containing metadata about typed field values.\n      For form field attachment fields, it includes <code>has_attachments</code> per field_id.<br/>\n      Example: <code>{ \"ft123456789\": { \"has_attachments\": true } }</code><br/><br/>\n      <b>Note:</b> Do not modify the <code>meta-options</code> attribute - it is reserved for internal use."
      tags:
      - Tickets V2
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
      - name: project_id
        in: path
        required: true
        schema:
          type: string
      - name: uuid
        in: path
        description: unique identifier of the ticket
        required: true
        schema:
          type: string
      responses:
        '404':
          description: Ticket Not Found
        '406':
          description: Unsupported Accept Header
    delete:
      summary: Deletes specific ticket
      tags:
      - Tickets V2
      description: This API is used for deleting a specific ticket based on its uuid.
      security:
      - apiKey: []
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
      - name: project_id
        in: path
        required: true
        schema:
          type: string
      - name: uuid
        in: path
        description: unique identifier of the ticket
        required: true
        schema:
          type: string
      responses:
        '406':
          description: Unsupported Accept Header
    put:
      summary: Updates specific ticket
      tags:
      - Tickets V2
      description: "This API is used for updating the details of a specific ticket based on its uuid.<br/>\n      The response includes <b>typed_values_metadata</b> which contains metadata about form field attachments (e.g. has_attachments per field_id).<br/><br/>\n      <b>Note:</b> Do not modify the <code>meta-options</code> attribute - it is reserved for internal use."
      security:
      - apiKey: []
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
      - name: project_id
        in: path
        required: true
        schema:
          type: string
      - name: uuid
        in: path
        description: unique identifier of the ticket
        required: true
        schema:
          type: string
      - name: clean_up_assets
        in: query
        description: If set to true, triggers a background job to remove any orphaned assets (images, documents, audios, videos) that no longer belong to the ticket
        schema:
          type: boolean
      responses:
        '404':
          description: Ticket Not found
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  type: object
                  properties:
                    attributes:
                      $ref: '#/components/schemas/Ticket'
              required:
              - title
              - content
  /api/v2/{customer_id}/projects/{project_id}/tickets/{uuid}/mark_as_seen:
    get:
      summary: Marks specific ticket as seen
      tags:
      - Tickets V2
      description: 'This API is used for marking a specific ticket as seen if the request is done by the ticket asignee, else it returns whether or not the ticket was marked as seen. '
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
      - name: project_id
        in: path
        required: true
        schema:
          type: string
      - name: uuid
        in: path
        description: unique identifier of the ticket
        required: true
        schema:
          type: string
      responses:
        '406':
          description: Unsupported Accept Header
  /api/v2/{customer_id}/projects/{project_id}/tickets/export/pdf:
    post:
      summary: Exports filtered tickets as PDF
      tags:
      - Tickets V2
      description: ' This API is used for exporting tickets to pdf files based on their filter. '
      security:
      - apiKey: []
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
      - name: project_id
        in: path
        required: true
        schema:
          type: string
      - name: pagesize
        in: query
        description: Maximum is 500, default is 100
        schema:
          type: integer
      - name: last_sync_date
        in: query
        schema:
          type: string
      - name: sort
        in: query
        schema:
          type: string
      - name: filter[status_id]
        in: query
        description: "Simple status ID filter. Use status codes: 1=Open, 2=In-Progress, 3=Resolved, 4=Feedback, 5=Closed, 6=Rejected. Example: filter[status_id]=1 - Structured filter parameter supporting multiple conditions and predicates. You can use either simple or advanced format.<br/>\n      <b>Status ID Mapping:</b> 1 (lm)=Open, 2 (ol)=In-Progress, 3 (ma)=Resolved, 4 (ex)=Feedback, 5 (gk)=Closed, 6 (ky)=Rejected<br/>\n      <b>Simple Format:</b> `filter[{field}]={value}` - Direct field-value filtering<br/>\n      <b>Advanced Format:</b> `filter[{field}][][predicate]={predicate}&filter[{field}][][value][]={value}` - Complex filtering with predicates<br/>\n      <b>Supported Fields:</b> status_id, priority-id, assigned-to-id, author-id, subject, created-at, due-date, etc.<br/>\n      <b>Predicates:</b> eq (equals), neq (not equals), in (in list), not_in (not in list), like (contains), not_like (not contains), between (range), has (has value), has_not (no value), le (less/equal), ge (greater/equal)<br/>\n      <b>Simple Format Examples:</b><br/>\n      • Filter by status: `filter[status_id]=1` (Open tickets)<br/>\n      • Filter by priority: `filter[priority-id]=3` (High priority)<br/>\n      • Multiple simple filters: `filter[status_id]=1&filter[priority-id]=3`<br/>\n      <b>Advanced Format Examples:</b><br/>\n      • Status filtering with 'in': `filter[status_id][][predicate]=in&filter[status_id][][value][]=1&filter[status_id][][value][]=2`<br/>\n      • Text search with 'like': `filter[subject][][predicate]=like&filter[subject][][value][]=urgent`<br/>\n      • Date range filtering: `filter[created-at][][predicate]=between&filter[created-at][][value][]=2024-01-01&filter[created-at][][value][]=2024-12-31`<br/>\n      • Complex multiple conditions: `filter[status_id][][predicate]=eq&filter[status_id][][value][]=1&filter[priority-id][][predicate]=eq&filter[priority-id][][value][]=3`"
        schema:
          type: string
      - name: apply_filter
        in: query
        description: filterid, based on which the tickets should be filtered
        schema:
          type: string
      - name: search
        in: query
        description: keyword, based on which the tickets should be filtered
        schema:
          type: string
      - name: async
        in: query
        description: Set to true to force asynchronous (background) processing. When enabled, the response returns a job ID instead of the file directly.
        schema:
          type: boolean
      responses:
        '406':
          description: Unsupported Accept Header
  /api/v2/{customer_id}/projects/{project_id}/tickets/load_recurring_reminders:
    get:
      summary: Returns all recurring reminders
      tags:
      - Tickets V2
      description: This API returns all recurring reminders of the tickets of the logged in customer.
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
      - name: project_id
        in: path
        required: true
        schema:
          type: string
      - name: page
        in: query
        description: sets the number of pages for the returned reminders
        schema:
          type: integer
      - name: pagesize
        in: query
        description: sets the number of reminders that should be returned per page <br> Maximum is 500, default is 100
        schema:
          type: integer
      - name: last_sync_date
        in: query
        description: is a Unix Timestamp. If it is set, only reminders that were created after that timestamp will be returned
        schema:
          type: string
      responses:
        '406':
          description: unsupported accept header
  /api/v2/{customer_id}/projects/{project_id}/tickets/ticket_types_stats:
    get:
      summary: Returns the count of tickets per ticket type
      tags:
      - Tickets V2
      description: "This API returns the count of tickets per ticket types. Extra parameters can be added to filter the results.\n      <br> <b>Ticket Filtering </b>\n      You can filter the results by one of your created filters by providing its id to the apply_filter parameter.\n      <br><b>Example:  </b>ticket_types_stats?apply_filter=jpg\n      <br>Moreover, the results can be filtered based on any condition of the related model.\n      filter[author_id]=1 will list all tickets related to this author id.\n      filter[author_email]=1 will list all tickets related to this author email.\n      Multiple filters can be used at the same time.\n      <br><b>Example:  </b> filter[id][]=PN&filter[id][]=nE\n      <br><b>Available Models</b>: customer, ticket_type, project, component, status, ticket, author, assigned_to, updated_by, due_by, overdue_by, creation_period"
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
      - name: project_id
        in: path
        required: true
        schema:
          type: string
      - name: filter
        in: query
        schema:
          type: string
      - name: apply_filter
        in: query
        schema:
          type: string
      responses:
        '406':
          description: Unsupported Accept Header
  /api/v2/{customer_id}/projects/{project_id}/tickets/batch_update:
    put:
      summary: Updates multiple tickets at once
      tags:
      - Tickets V2
      description: "This API is used for updating multiple tickets at once based on the provided filteration. However, no filter will update all the data of the project.\n      <br />\n      <b>Filtering </b>\n      You can filter the tickets by one of your created filters by providing its id to the apply_filter attribute.\n      Moreover, the tickets can be filtered based on any condition of the related model. These have to be set in the filter object of the body.\n      Multiple filters can be used at the same time.\n      <br />\n      Example:\n      <br />\n\n      {\n        \"apply_filter\":\"mod\",\n        \"filter\":{\n           \"uuid\":[\n              {\n                 \"predicate\":\"in\",\n                 \"value\":[\n                    \"b404f669-e02a-4273-bcff-aac72b31386f\",\n                    \"fa30521c-bf68-4246-b50f-29fd9c91ee5f\"\n                 ]\n              }\n           ]\n        },\n        \"data\":{\n           \"attributes\":{\n              \"priority-id\":\"ol\"\n           },\n           \"obk\":{\n              \"tf37e04757dabbca63\":\"4\",\n              \"tf7ae8b29ea4b4c1e9\":[\n                 \"makw\"\n              ],\n              \"typed-values-metadata\":{\n                 \"tf37e04757dabbca63\":{\n                    \"note\":\"observation details\",\n                    \"has_attachments\":true\n                 }\n              }\n           }\n        }\n     }\n\n      <br /><br />\n      <b>CheckList Fields in Batch Update</b><br />\n      When updating CheckList fields (CustomFields::CheckListType), typed-values-metadata must be placed inside the ticket_type_id bucket alongside the typed values. The server extracts it automatically.<br />\n      <b>Silent Skip Behavior:</b> If a checklist field requires a mandatory note or attachment and the metadata is not provided, the checklist field update is silently skipped for that ticket. Other fields in the same batch update are still applied normally."
      x-websocket-response:
        channel: user_{customerId}_{userId}
        message_type: cable-events
        payload:
          type: object
          properties:
            multiupdate-progress:
              type: integer
              description: Always 1, signals completion
            failed-count:
              type: integer
              description: Number of tickets that failed to update
      security:
      - apiKey: []
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
      - name: project_id
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Tickets Updated
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: integer
                  subject:
                    type: string
                required:
                - id
                - subject
        '406':
          description: Unsupported Accept Header
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                apply_filer:
                  type: string
                data:
                  type: object
                  properties:
                    attributes:
                      type: object
                      properties:
                        field-name:
                          type: string
                          description: 'the key should be set to the field name of the field that should be changed <br\> -- the value of the field name is the new value that the user wants to set - example priority-id: "ol"'
                    ticket_type_id:
                      type: object
                      properties:
                        typed-field-id:
                          type: string
                          description: -- typed values have to be grouped by the ticket types, the type of their values depends on the field type
                        typed-values-metadata:
                          type: object
                          description: Metadata for checklist fields (notes, attachment flags). Keys are typed field IDs, values are objects with optional 'note' (string) and 'has_attachments' (boolean)
                filter:
                  type: object
                  properties:
                    uuid:
                      type: array
                      items:
                        type: string
                    component_id:
                      type: string
                      description: -is optional
                  description: ' filter contains the filter data and an array of all the uuids of the tickets that should be updated  <br />  a filter consists of a filter field key, a predicate and a value - there can be multiple field keys and values'
              required:
              - title
              - content
  /api/v2/{customer_id}/projects/{project_id}/tickets/multi_update:
    put:
      summary: Updates multiple tickets with array
      tags:
      - Tickets V2
      description: This API is used for updating multiple tickets at once based on the uuid.
      x-websocket-response:
        channel: user_{customerId}_{userId}
        message_type: cable-events
        payload:
          type: object
          properties:
            multiupdate-progress:
              type: integer
              description: Always 1, signals completion
            failed-count:
              type: integer
              description: Number of tickets that failed to update
      security:
      - apiKey: []
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
      - name: project_id
        in: path
        required: true
        schema:
          type: string
      responses:
        '406':
          description: Unsupported Accept Header
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  type: array
                  items:
                    type: object
                    properties:
                      attributes:
                        type: object
                        properties:
                          uuid:
                            type: string
                            description: The unique identifier of the ticket
                          su

# --- truncated at 32 KB (59 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/planradar/refs/heads/main/openapi/planradar-tickets-v2-api-openapi.yml