Canonical Job API

The Job API from Canonical — 7 operation(s) for job.

Operations 9

Each operation below carries the questions people ask an LLM about it and the instructions they give an agent to run it. Generated by API Evangelist overlay

GET /v1/job Pick up the next job from a queue · Request a job to run from supported queues #
Ask an LLM
“How does an agent ask the server for the next job on its queues?”
“What does an agent get back when no job is waiting on its queues?”
Tell an agent
Request the next available job for my agent's queues.
Fetch a job to run from the queues this agent supports.
POST /v1/job Submit a test job · Add a job to the queue #
Ask an LLM
“How do I submit a test job to a Testflinger queue?”
“Can I set a priority and a global timeout when I submit a job?”
Tell an agent
Submit a job to queue {job_queue}.
Queue job {name} on {job_queue} with priority {job_priority}.
GET /v1/job/search Search jobs by tag · Search for jobs by tags #
Ask an LLM
“Can I find all jobs carrying a certain tag?”
“Which of my tagged jobs are still running?”
Tell an agent
Search for jobs tagged {tags}.
Find jobs matching {match} of tags {tags} in state {state}.
GET /v1/job/{job_id} Get a job's definition · Request the json job definition for a specified job, even if it has #
Ask an LLM
“What did I submit as the definition of a job that already ran?”
“Can I see the provision and test data of a past job?”
Tell an agent
Show the job definition for {job_id}.
Get the submitted JSON of job {job_id}.
POST /v1/job/{job_id}/action Take an action on a job · Take action on the job status for a specified job ID #
Ask an LLM
“How do I change the status of a job that is queued or running?”
“Which job actions does the server accept for a job ID?”
Tell an agent
Apply action {action} to job {job_id}.
Send the {action} action to job {job_id}.
POST /v1/job/{job_id}/events Forward job status events to a webhook · Post status updates from the agent to the server to be forwarded #
Ask an LLM
“How does an agent push job status events to the webhook the user registered?”
“Can job events be forwarded to the configured status webhook?”
Tell an agent
Post events {events} for job {job_id} to webhook {job_status_webhook}.
Forward job {job_id} status updates to {job_status_webhook}.
GET /v1/job/{job_id}/position Get a job's place in the queue · Return the position of the specified jobid in the queue #
Ask an LLM
“How many jobs are ahead of mine in the queue?”
“Has my queued job moved up yet?”
Tell an agent
Show the queue position of job {job_id}.
Tell me where job {job_id} sits in its queue.
GET /v1/job/{job_id}/attachments Download a job's attachments · Return the attachments bundle for a specified job_id #
Ask an LLM
“Where can an agent download the files attached to a job?”
“Can I retrieve the attachment tarball I uploaded with a job?”
Tell an agent
Download the attachments bundle for job {job_id}.
Get the attachment tarball of job {job_id}.
POST /v1/job/{job_id}/attachments Upload a job's attachments · Post attachment bundle for a specified job_id #
Ask an LLM
“How do I attach local files to a job I submitted?”
“Can I send an attachment bundle along with a test job?”
Tell an agent
Upload the attachments bundle for job {job_id}.
Attach this tarball to job {job_id}.

Documentation

Specifications

Other Resources

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/canonical:canonical-job-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

canonical-job-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Testflinger Job API
  version: 1.0.0
servers:
- url: https://testflinger.ps7.canonical.com/
tags:
- name: Job
paths:
  /v1/job:
    get:
      parameters: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Job'
          description: Successful response
        '204':
          content:
            application/json:
              schema:
                type: object
                properties: {}
          description: No job found
      tags:
      - Job
      summary: Request a job to run from supported queues
      description: 'The agent must identify itself via the ``agent_name`` cookie. One or more

        ``queue`` query parameters must be supplied; the server returns the first

        available job across those queues.


        Any secrets referenced in the job are resolved against the secrets store

        at this point. Secrets that are inaccessible (store unreachable, path not

        found, or insufficient permissions) are silently resolved to an empty

        string rather than causing the request to fail. Agents must therefore

        handle the possibility of empty secret values.'
      operationId: getV1Job
      x-operation-id-source: derived
    post:
      parameters: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JobId'
          description: Successful response
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationError'
          description: Validation error
      tags:
      - Job
      summary: Add a job to the queue
      description: 'The ``job_queue`` field in the submitted JSON determines which queue the

        job is placed on. All other fields are passed through to the agent

        unchanged.


        Returns HTTP 422 if the job references secrets that are inaccessible at

        submission time (e.g. the secrets store is unreachable or the secret path

        does not exist for the submitting client).'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Job'
      operationId: postV1Job
      x-operation-id-source: derived
  /v1/job/search:
    get:
      parameters:
      - in: query
        name: tags
        description: List of tags to search for
        schema:
          type: array
          items:
            type: string
        required: false
        explode: true
        style: form
      - in: query
        name: match
        description: Match mode - 'all' or 'any' (default 'any')
        schema:
          type: string
          enum:
          - any
          - all
        required: false
      - in: query
        name: state
        description: List of job states to include
        schema:
          type: array
          items:
            type: string
            enum:
            - setup
            - provision
            - firmware_update
            - test
            - allocate
            - allocated
            - reserve
            - cleanup
            - cancelled
            - completed
            - active
        required: false
        explode: true
        style: form
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JobSearchResponse'
          description: Successful response
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationError'
          description: Validation error
      tags:
      - Job
      summary: Search for jobs by tags
      operationId: getV1JobSearch
      x-operation-id-source: derived
  /v1/job/{job_id}:
    get:
      parameters:
      - in: path
        name: job_id
        schema:
          type: string
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JobOut'
          description: Successful response
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPError'
          description: Not found
      tags:
      - Job
      summary: Request the json job definition for a specified job, even if it has
      description: 'already run.


        :param job_id:

        UUID as a string for the job

        :return:

        JSON data for the job or error string and http error'
      operationId: getV1JobByJobId
      x-operation-id-source: derived
  /v1/job/{job_id}/action:
    post:
      parameters:
      - in: path
        name: job_id
        schema:
          type: string
        required: true
      responses:
        '200':
          content:
            application/json:
              schema: {}
          description: Successful response
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationError'
          description: Validation error
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPError'
          description: Not found
      tags:
      - Job
      summary: Take action on the job status for a specified job ID
      description: ':param job_id:

        UUID as a string for the job'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ActionIn'
      operationId: postV1JobByJobIdAction
      x-operation-id-source: derived
  /v1/job/{job_id}/events:
    post:
      parameters:
      - in: path
        name: job_id
        schema:
          type: string
        required: true
      responses:
        '200':
          content:
            application/json:
              schema: {}
          description: Successful response
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationError'
          description: Validation error
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPError'
          description: Not found
      tags:
      - Job
      summary: Post status updates from the agent to the server to be forwarded
      description: 'to the server-configured webhook url.


        The json sent to this endpoint may contain data such as the following:

        {

        "agent_id": "",

        "job_queue": "",

        "job_status_webhook": "",

        "events": [

        {

        "event_name": "",

        "timestamp": "",

        "detail": ""

        },

        ...

        ]

        }


        :param job_id: UUID as a string for the job

        :param json_data: JSON data containing the status updates and webhook URL'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StatusUpdate'
      operationId: postV1JobByJobIdEvents
      x-operation-id-source: derived
  /v1/job/{job_id}/position:
    get:
      parameters:
      - in: path
        name: job_id
        schema:
          type: string
        required: true
      responses:
        '200':
          content:
            application/json:
              schema: {}
          description: Successful response
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPError'
          description: Not found
      tags:
      - Job
      summary: Return the position of the specified jobid in the queue
      operationId: getV1JobByJobIdPosition
      x-operation-id-source: derived
  /v1/job/{job_id}/attachments:
    get:
      parameters:
      - in: path
        name: job_id
        schema:
          type: string
        required: true
      responses:
        '200':
          content:
            application/json:
              schema: {}
          description: Successful response
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPError'
          description: Not found
      tags:
      - Job
      summary: Return the attachments bundle for a specified job_id
      description: ':param job_id:

        UUID as a string for the job

        :return:

        send_file stream of attachment tarball to download'
      operationId: getV1JobByJobIdAttachments
      x-operation-id-source: derived
    post:
      parameters:
      - in: path
        name: job_id
        schema:
          type: string
        required: true
      responses:
        '200':
          content:
            application/json:
              schema: {}
          description: Successful response
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPError'
          description: Not found
      tags:
      - Job
      summary: Post attachment bundle for a specified job_id
      description: ':param job_id:

        UUID as a string for the job'
      operationId: postV1JobByJobIdAttachments
      x-operation-id-source: derived
components:
  schemas:
    TestData:
      type: object
      properties:
        test_cmds:
          type: string
        attachments:
          type: array
          items:
            $ref: '#/components/schemas/Attachment'
        test_username:
          type: string
        test_password:
          type: string
        secrets:
          type: object
          additionalProperties:
            type: string
            pattern: ^[a-zA-Z0-9_/-]+$
      additionalProperties: false
    ProvisionData:
      type: object
      properties: {}
      additionalProperties: false
    JobId:
      type: object
      properties:
        job_id:
          type: string
      required:
      - job_id
      additionalProperties: false
    Attachment:
      type: object
      properties:
        agent:
          type: string
        device:
          type: string
      required:
      - agent
      additionalProperties: false
    JobSearchResponse:
      type: object
      properties:
        jobs:
          type: array
          items:
            $ref: '#/components/schemas/Job'
      required:
      - jobs
      additionalProperties: false
    ReserveData:
      type: object
      properties:
        ssh_keys:
          type: array
          items:
            type: string
            pattern: ^(lp|gh):(\S+)$
        timeout: {}
      additionalProperties: false
    JobEvent:
      type: object
      properties:
        event_name:
          type: string
        timestamp:
          type: string
        detail:
          type: string
      required:
      - event_name
      - timestamp
      additionalProperties: false
    Job:
      type: object
      properties:
        job_id:
          type: string
        parent_job_id:
          type: string
        name:
          type: string
        tags:
          type: array
          items:
            type: string
        job_queue:
          type: string
          minLength: 1
        global_timeout:
          type: integer
        output_timeout:
          type: integer
        allocation_timeout:
          type: integer
        provision_data:
          anyOf:
          - type:
            - object
            - 'null'
          - $ref: '#/components/schemas/ProvisionData'
        firmware_update_data:
          type: object
          additionalProperties: {}
        test_data:
          $ref: '#/components/schemas/TestData'
        allocate_data:
          type: object
          additionalProperties: {}
        reserve_data:
          $ref: '#/components/schemas/ReserveData'
        job_status_webhook:
          type: string
        job_priority:
          type: integer
        exclude_agents:
          type: array
          items:
            type: string
        debug:
          type: boolean
      required:
      - job_queue
      additionalProperties: false
    JobOut:
      type: object
      properties:
        job_id:
          type: string
        parent_job_id:
          type: string
        name:
          type: string
        tags:
          type: array
          items:
            type: string
        job_queue:
          type: string
          minLength: 1
        global_timeout:
          type: integer
        output_timeout:
          type: integer
        allocation_timeout:
          type: integer
        provision_data:
          anyOf:
          - type:
            - object
            - 'null'
          - $ref: '#/components/schemas/ProvisionData'
        firmware_update_data:
          type: object
          additionalProperties: {}
        test_data:
          $ref: '#/components/schemas/TestData'
        allocate_data:
          type: object
          additionalProperties: {}
        reserve_data:
          $ref: '#/components/schemas/ReserveData'
        job_status_webhook:
          type: string
        job_priority:
          type: integer
        exclude_agents:
          type: array
          items:
            type: string
        debug:
          type: boolean
        submitted_by:
          type:
          - string
          - 'null'
          default: null
      required:
      - job_queue
      additionalProperties: false
    HTTPError:
      properties:
        detail:
          type: object
        message:
          type: string
      type: object
    ActionIn:
      type: object
      properties:
        action:
          type: string
          enum:
          - cancel
      required:
      - action
      additionalProperties: false
    StatusUpdate:
      type: object
      properties:
        agent_id:
          type: string
        job_queue:
          type: string
        job_status_webhook:
          type: string
          format: url
        events:
          type: array
          items:
            $ref: '#/components/schemas/JobEvent'
      required:
      - job_status_webhook
      additionalProperties: false
    ValidationError:
      properties:
        detail:
          type: object
          properties:
            <location>:
              type: object
              properties:
                <field_name>:
                  type: array
                  items:
                    type: string
        message:
          type: string
      type: object