GitHub Raw JSON API

semaphoreui / semaphore

13,926 Go

Modern UI and powerful API for Ansible, Terraform/OpenTofu/Terragrunt, PowerShell and other DevOps tools.

semaphore Specification

Located in web/public/swagger/api-docs.yml on branch HEAD

2.0 (YAML) YAML 65.3 KB
Raw YAML Specification
---
swagger: '2.0'
info:
  title: Semaphore API
  description: |
    Semaphore API provides endpoints for managing and interacting with the Semaphore UI.
    This documentation outlines the available operations and data models.
  version: "2.16.14"

consumes:
  - application/json
produces:
  - application/json
  - text/plain; charset=utf-8

tags:
  - name: authentication
    description: Authentication, Logout & API Tokens
  - name: project
    description: Everything related to a project
  - name: user
    description: User-related API
  - name: integration
    description: Integration API

schemes:
  - http
  - https

basePath: /api

definitions:
  App:
    type: object

  Pong:
    type: string
    x-example: pong

  Login:
    type: object
    properties:
      auth:
        type: string
        description: Username/Email address
        x-example: [email protected]
      password:
        type: string
        format: password
        description: Password

  LoginMetadata:
    type: object
    properties:
      oidc_providers:
        type: array
        description: List of OIDC providers
        items:
          type: object
          properties:
            id:
              type: string
              description: ID of the provider, used in the login URL
              x-example: mysso
            name:
              type: string
              description: Text to show on the login button
              x-example: Sign in with MySSO

  UserRequest:
    type: object
    properties:
      name:
        type: string
        x-example: Integration Test User
        example: Integration Test User
      username:
        type: string
        x-example: test-user
        example: test-user
      email:
        type: string
        x-example: [email protected]
        example: [email protected]
      password:
        type: string
        format: password
      alert:
        type: boolean
      admin:
        type: boolean
      external:
        type: boolean

  UserPutRequest:
    type: object
    properties:
      name:
        type: string
        x-example: Integration Test User2
        example: Integration Test User2
      username:
        type: string
        x-example: test-user2
        example: test-user2
      email:
        type: string
        x-example: [email protected]
        example: [email protected]
      alert:
        type: boolean
      admin:
        type: boolean

  User:
    type: object
    properties:
      id:
        type: integer
        minimum: 1
      name:
        type: string
      username:
        type: string
      email:
        type: string
      created:
        type: string
      alert:
        type: boolean
      admin:
        type: boolean
      external:
        type: boolean

  ProjectUser:
    type: object
    properties:
      id:
        type: integer
        minimum: 1
      name:
        type: string
      username:
        type: string
      role:
        type: string
        enum: [owner, manager, task_runner, guest]

  ProjectInvite:
    type: object
    properties:
      id:
        type: integer
        minimum: 1
      project_id:
        type: integer
        minimum: 1
      user_id:
        type: integer
        minimum: 1
        description: User ID for user-based invites (optional)
      email:
        type: string
        format: email
        description: Email address for email-based invites (optional)
      role:
        type: string
        enum: [owner, manager, task_runner, guest]
        example: manager
      status:
        type: string
        enum: [pending, accepted, declined, expired]
        example: pending
      inviter_user_id:
        type: integer
        minimum: 1
        description: ID of the user who created the invite
      created:
        type: string
        format: date-time
        description: When the invite was created
      expires_at:
        type: string
        format: date-time
        description: When the invite expires (optional)
      accepted_at:
        type: string
        format: date-time
        description: When the invite was accepted (optional)
      inviter_user:
        $ref: "#/definitions/User"
        description: Details of the user who created the invite
      user:
        $ref: "#/definitions/User"
        description: Details of the invited user (for user-based invites)

  ProjectInviteRequest:
    type: object
    properties:
#      user_id:
#        type: integer
#        minimum: 1
#        description: User ID to invite (use either user_id or email, not both)
      email:
        type: string
        format: email
        description: Email address to invite (use either user_id or email, not both)
        x-example: [email protected]
      role:
        type: string
        enum: [owner, manager, task_runner, guest]
        example: manager
      expires_at:
        type: string
        format: date-time
        description: When the invite should expire (optional, defaults to 7 days)
    required:
      - role

  AcceptInviteRequest:
    type: object
    properties:
      token:
        type: string
        description: The invitation token
        x-example: "a1b2c3d4e5f6..."
    required:
      - token

  ProjectBackup:
    type: object
    example: {"meta":{"name":"homelab","alert":true,"alert_chat":"Test","max_parallel_tasks":0,"type":null},"templates":[{"inventory":"Build","repository":"Demo","environment":"Empty","name":"Build","playbook":"build.yml","arguments":"[]","allow_override_args_in_task":false,"description":"Build Job","vault_key":null,"type":"build","start_version":"1.0.0","build_template":null,"view":"Build","autorun":false,"survey_vars":[],"suppress_success_alerts":false,"cron":"* * * * *"}],"repositories":[{"name":"Demo","git_url":"https://github.com/semaphoreui/semaphore-demo.git","git_branch":"main","ssh_key":"None"}],"keys":[{"name":"None","type":"none"},{"name":"Vault Password","type":"login_password"}],"views":[{"title":"Build","position":0}],"inventories":[{"name":"Build","inventory":"","ssh_key":"None","become_key":"None","type":"static"},{"name":"Dev","inventory":"","ssh_key":"None","become_key":"None","type":"file"},{"name":"Prod","inventory":"","ssh_key":"None","become_key":"None","type":"file"}],"environments":[{"name":"Empty","password":null,"json":"{}","env":null}]}
    properties:
      meta:
        type: object
        properties:
          name:
            type: string
          alert:
            type: boolean
          alert_chat:
            type: string
          max_parallel_tasks:
            type: integer
            minimum: 0
          type:
            type: string
      templates:
        type: array
        items:
          type: object
          properties:
            inventory:
              type: string
            repository:
              type: string
            environment:
              type: string
            view:
              type: string
            name:
              type: string
            playbook:
              type: string
            arguments:
              type: string
            description:
              type: string
            allow_override_args_in_task:
              type: boolean
            suppress_success_alerts:
              type: boolean
            cron:
              type: string
            build_template:
              type: string
            autorun:
              type: boolean
            survey_vars:
              type: string
            start_version:
              type: string
            type:
              type: string
            vault_key:
              type: string
            allow_override_branch_in_task:
              type: boolean
      repositories:
        type: array
        items:
          type: object
          properties:
            name:
              type: string
            git_url:
              type: string
            git_branch:
              type: string
            ssh_key:
              type: string
      keys:
        type: array
        items:
          type: object
          properties:
            name:
              type: string
            type:
              type: string
              enum: [ssh, login_password, none]
      views:
        type: array
        items:
          type: object
          properties:
            name:
              type: string
            position:
              type: integer
              minimum: 0
      inventories:
        type: array
        items:
          type: object
          properties:
            name:
              type: string
            inventory:
              type: string
            ssh_key:
              type: string
            become_key:
              type: string
            type:
              type: string
              enum: [static, static-yaml, file]
      environments:
        type: array
        items:
          type: object
          properties:
            name:
              type: string
            password:
              type: string
            json:
              type: string
            env:
              type: string

  APIToken:
    type: object
    properties:
      id:
        type: string
      created:
        type: string
      #        pattern: ^\d{4}-(?:0[0-9]{1}|1[0-2]{1})-[0-9]{2}T\d{2}:\d{2}:\d{2}Z$
      expired:
        type: boolean
      user_id:
        type: integer
        minimum: 1
      name:
        type: string

  ProjectRequest:
    type: object
    properties:
      name:
        type: string
        example: Test
      alert:
        type: boolean
      alert_chat:
        type: string
        x-nullable: true
        example: Test
      max_parallel_tasks:
        type: integer
        minimum: 0
      type:
        type: string
      demo:
        description: Create Demo project resources?
        type: boolean

  Project:
    type: object
    properties:
      id:
        type: integer
        minimum: 1
      name:
        type: string
        example: Test
      created:
        type: string
      #        pattern: ^\d{4}-(?:0[0-9]{1}|1[0-2]{1})-[0-9]{2}T\d{2}:\d{2}:\d{2}Z$
      alert:
        type: boolean
      alert_chat:
        type: string
        x-nullable: true
        example: Test
      max_parallel_tasks:
        type: integer
        minimum: 0
      type:
        type: string

  AccessKeyRequest:
    type: object
    properties:
      id:
        type: integer
      name:
        type: string
        x-example: None
        example: None
      type:
        type: string
        enum: [none, ssh, login_password]
        x-example: none
      project_id:
        type: integer
        minimum: 1
        x-example: 2
      override_secret:
        type: boolean
      login_password:
        type: object
        properties:
          password:
            type: string
            x-example: password
            example: password
          login:
            type: string
            x-example: username
            example: username
      ssh:
        type: object
        properties:
          login:
            type: string
            x-example: user
            example: user
          passphrase:
            type: string
            x-example: passphrase
            example: passphrase
          private_key:
            type: string
            x-example: private key
            example: private key

  AccessKey:
    type: object
    properties:
      id:
        type: integer
      name:
        type: string
        example: Test
      type:
        type: string
        enum: [none, ssh, login_password]
      project_id:
        type: integer

  EnvironmentSecret:
    type: object
    properties:
      id:
        type: integer
      name:
        type: string
      type:
        type: string
        enum: [env, var]

  EnvironmentSecretRequest:
    type: object
    properties:
      id:
        type: integer
      name:
        type: string
        example: Test
      secret:
        type: string
      type:
        type: string
        enum: [env, var]
      operation:
        type: string
        enum: [create, update, delete]

  EnvironmentRequest:
    type: object
    properties:
      id:
        type: integer
        example: 1
      name:
        type: string
        example: Test
      project_id:
        type: integer
        minimum: 1
      password:
        type: string
      json:
        type: string
        example: '{}'
      env:
        type: string
        example: '{}'
      secrets:
        type: array
        items:
          $ref: '#/definitions/EnvironmentSecretRequest'

  Environment:
    type: object
    properties:
      id:
        type: integer
        minimum: 1
      name:
        type: string
        example: Test
      project_id:
        type: integer
        minimum: 1
      password:
        type: string
      json:
        type: string
        example: '{}'
      env:
        type: string
        example: '{}'
      secrets:
        type: array
        items:
          $ref: '#/definitions/EnvironmentSecret'

  InventoryRequest:
    type: object
    properties:
      id:
        type: integer
      name:
        type: string
        example: Test
      project_id:
        type: integer
        minimum: 1
      inventory:
        type: string
      ssh_key_id:
        type: integer
        minimum: 1
      become_key_id:
        type: integer
        minimum: 1
      repository_id:
        type: integer
        minimum: 1
      type:
        type: string
        enum: [static, static-yaml, file, terraform-workspace]

  Inventory:
    type: object
    properties:
      id:
        type: integer
      name:
        type: string
        example: Test
      project_id:
        type: integer
      inventory:
        type: string
      ssh_key_id:
        type: integer
      become_key_id:
        type: integer
      repository_id:
        type: integer
      type:
        type: string
        enum: [static, static-yaml, file, terraform-workspace]

  Integration:
    type: object
    properties:
      id:
        type: integer
      name:
        type: string
        example: deploy
      project_id:
        type: integer
        minimum: 1
      template_id:
        type: integer
        minimum: 1
      auth_method:
        type: string
        example: none
      auth_secret_id:
        type: integer
        x-nullable: true
      auth_header:
        type: string
      searchable:
        type: boolean
      task_params:
        $ref: '#/definitions/TaskPrams'

  IntegrationRequest:
    type: object
    properties:
      id:
        type: integer
      name:
        type: string
        example: deploy
      project_id:
        type: integer
      template_id:
        type: integer
      auth_method:
        type: string
        example: none
      auth_secret_id:
        type: integer
        x-nullable: true
      auth_header:
        type: string
      searchable:
        type: boolean
      task_params:
        $ref: '#/definitions/TaskPrams'

  IntegrationExtractValueRequest:
    type: object
    properties:
      name:
        type: string
        example: deploy
      value_source:
        type: string
        enum: [body, header]
      body_data_type:
        type: string
        enum: [json, xml, string]
      key:
        type: string
        example: key
      variable:
        type: string
        example: variable
      variable_type:
        type: string
        enum: [environment, task]

  IntegrationExtractValue:
    type: object
    properties:
      id:
        type: integer
      name:
        type: string
        example: extract this value
      value_source:
        type: string
        enum: [body, header]
      body_data_type:
        type: string
        enum: [json, xml, string]
      key:
        type: string
        example: key
      variable:
        type: string
        example: variable
      variable_type:
        type: string
        enum: [environment, task]
      integration_id:
        type: integer

  IntegrationMatcherRequest:
    type: object
    properties:
      name:
        type: string
        example: deploy
      match_type:
        type: string
        enum: [body, header]
      method:
        type: string
        enum: [equals, unequals, contains]
      body_data_type:
        type: string
        enum: [json, xml, string]
      key:
        type: string
        example: key
      value:
        type: string
        example: value

  IntegrationMatcher:
    type: object
    properties:
      id:
        type: integer
      integration_id:
        type: integer
      name:
        type: string
        example: deploy
      match_type:
        type: string
        enum: [body, header]
      method:
        type: string
        enum: [equals, unequals, contains]
      body_data_type:
        type: string
        enum: [json, xml, string]
      key:
        type: string
        example: key
      value:
        type: string
        example: value

  IntegrationAlias:
    type: object
    properties:
      id:
        type: integer
      url:
        type: string

  RepositoryRequest:
    type: object
    properties:
      id:
        type: integer
      name:
        type: string
        example: Test
      project_id:
        type: integer
      git_url:
        type: string
        example: [email protected]
      git_branch:
        type: string
        example: master
      ssh_key_id:
        type: integer
  
  Repository:
    type: object
    properties:
      id:
        type: integer
      name:
        type: string
        example: Test
      project_id:
        type: integer
      git_url:
        type: string
        example: [email protected]
      git_branch:
        type: string
        example: master
      ssh_key_id:
        type: integer

  Task:
    type: object
    properties:
      id:
        type: integer
        example: 23
      template_id:
        type: integer
      status:
        type: string
      playbook:
        type: string
      environment:
        type: string
      secret:
        type: string
      arguments:
        type: string
      git_branch:
        type: string
      message:
        type: string
      inventory_id:
        type: integer
      params:
        allOf:
          - $ref: '#/definitions/AnsibleTaskParams'
          - $ref: '#/definitions/TerraformTaskParams'
      limit:
        type: string

  AnsibleTaskParams:
    type: object
    properties:
      debug:
        type: boolean
      dry_run:
        type: boolean
      diff:
        type: boolean
      limit:
        type: array
        items:
          type: string
      tags:
        type: array
        items:
          type: string
      skip_tags:
        type: array
        items:
          type: string
      skip_galaxy_install:
        type: boolean

  TerraformTaskParams:
    type: object
    properties:
      plan:
        type: boolean
      destroy:
        type: boolean
      auto_approve:
        type: boolean
      upgrade:
        type: boolean

  TaskPrams:
    type: object
    properties:
      environment:
        type: string
      git_branch:
        type: string
      message:
        type: string
      inventory_id:
        type: integer
      arguments:
        type: string
      params:
        allOf:
          - $ref: '#/definitions/AnsibleTaskParams'
          - $ref: '#/definitions/TerraformTaskParams'

  TaskOutput:
    type: object
    properties:
      task_id:
        type: integer
        example: 23
      time:
        type: string
        format: date-time
      output:
        type: string

  TemplateRequest:
    type: object
    properties:
      id:
        type: integer
        example: 1
      project_id:
        type: integer
        minimum: 1
      inventory_id:
        type: integer
        minimum: 1
      repository_id:
        type: integer
        minimum: 1
      environment_id:
        type: integer
        minimum: 1
      view_id:
        type: integer
        minimum: 1
      vaults:
        type: array
        items:
          $ref: '#/definitions/TemplateVault'
      name:
        type: string
        example: Test
      playbook:
        type: string
        example: test.yml
      arguments:
        type: string
        example: '[]'
      description:
        type: string
        example: Hello, World!
      allow_override_args_in_task:
        type: boolean
        example: false
      limit:
        type: string
        example: ''
      suppress_success_alerts:
        type: boolean
      app:
        type: string
        example: ansible
      git_branch:
        type: string
        example: main
      survey_vars:
        type: array
        items:
          $ref: "#/definitions/TemplateSurveyVar"
      type:
        type: string
        enum: ["", build, deploy]
      start_version:
        type: string
      build_template_id:
        type: integer
      autorun:
        type: boolean
      task_params:
        $ref: '#/definitions/TaskPrams'

  Template:
    type: object
    properties:
      id:
        type: integer
        minimum: 1
      project_id:
        type: integer
        minimum: 1
      inventory_id:
        type: integer
        minimum: 1
      repository_id:
        type: integer
      environment_id:
        type: integer
        minimum: 1
      view_id:
        type: integer
        minimum: 1
      name:
        type: string
        example: Test
      playbook:
        type: string
        example: test.yml
      arguments:
        type: string
        example: '[]'
      description:
        type: string
        example: Hello, World!
      allow_override_args_in_task:
        type: boolean
        example: false
      suppress_success_alerts:
        type: boolean
      app:
        type: string
      git_branch:
        type: string
        example: main
      type:
        type: string
        enum: ["", build, deploy]
      start_version:
        type: string
      build_template_id:
        type: integer
      autorun:
        type: boolean
      survey_vars:
        type: array
        items:
          $ref: "#/definitions/TemplateSurveyVar"
      vaults:
        type: array
        items:
          $ref: "#/definitions/TemplateVault"
      task_params:
        $ref: '#/definitions/TaskPrams'

  TemplateSurveyVar:
    type: object
    properties:
      name:
        type: string
      title:
        type: string
      description:
        type: string
      type:
        type: string
        enum: ["", int, enum, secret] # String => "", Integer => "int"
        example: int
      required:
        type: boolean
      values:
        type: array
        items:
          $ref: "#/definitions/TemplateSurveyVarValue"

  TemplateSurveyVarValue:
    type: object
    properties:
      name:
        type: string
      value:
        type: string

  TemplateVault:
    type: object
    properties:
      id:
        type: integer
      name:
        type: string
        example: default
      type:
        type: string
        enum: [password, script]
        example: script
      vault_key_id:
        type: integer
      script:
        type: string
        example: path/to/script-client.py

  ScheduleRequest:
    type: object
    properties:
      id:
        type: integer
      cron_format:
        type: string
        x-example: "* * * 1 *"
        example: "* * * 1 *"
      project_id:
        type: integer
      template_id:
        type: integer
      name:
        type: string
      active:
        type: boolean
      run_at:
        type: string
        format: date-time
      type:
        type: string
        enum: ['', 'run_at']
      task_params:
        $ref: '#/definitions/TaskPrams'

  Schedule:
    type: object
    properties:
      id:
        type: integer
      cron_format:
        type: string
      project_id:
        type: integer
      template_id:
        type: integer
      name:
        type: string
      active:
        type: boolean
      run_at:
        type: string
        format: date-time
      type:
        type: string
        enum: ['', 'run_at']
      task_params:
        $ref: '#/definitions/TaskPrams'

  ViewRequest:
    type: object
    properties:
      id:
        type: integer
        minimum: 1
      title:
        type: string
        example: Test
      project_id:
        type: integer
        minimum: 1
      position:
        type: integer
        minimum: 1
  View:
    type: object
    properties:
      id:
        type: integer
      title:
        type: string
      project_id:
        type: integer
      position:
        type: integer

  Runner:
    type: object
    properties:
      token:
        type: string

  Event:
    type: object
    properties:
      project_id:
        type: integer
      user_id:
        type: integer
      object_id:
        type: integer
      object_type:
        type: string
      description:
        type: string

  InfoType:
    type: object
    properties:
      version:
        type: string
      ansible:
        type: string
      web_host:
        type: string
      use_remote_runner:
        type: boolean
      auth_methods:
        type: object
      git_client:
        type: string
      schedule_timezone:
        type: string
      features:
        type: object

securityDefinitions:
  cookie:
    type: apiKey
    name: Cookie
    in: header
  bearer:
    type: apiKey
    name: Authorization
    in: header

security:
  - bearer: []
  - cookie: []

parameters:
  project_id:
    name: project_id
    description: Project ID
    in: path
    type: integer
    required: true
    x-example: 1
  user_id:
    name: user_id
    description: User ID
    in: path
    type: integer
    required: true
    x-example: 2
  key_id:
    name: key_id
    description: key ID
    in: path
    type: integer
    required: true
    x-example: 3
  repository_id:
    name: repository_id
    description: repository ID
    in: path
    type: integer
    required: true
    x-example: 4
  inventory_id:
    name: inventory_id
    description: inventory ID
    in: path
    type: integer
    required: true
    x-example: 5
  environment_id:
    name: environment_id
    description: environment ID
    in: path
    type: integer
    required: true
    x-example: 6
  template_id:
    name: template_id
    description: template ID
    in: path
    type: integer
    required: true
    x-example: 7
  task_id:
    name: task_id
    description: task ID
    in: path
    type: integer
    required: true
    x-example: 8
  schedule_id:
    name: schedule_id
    description: schedule ID
    in: path
    type: integer
    required: true
    x-example: 9
  view_id:
    name: view_id
    description: view ID
    in: path
    type: integer
    required: true
    x-example: 10
  integration_id:
    name: integration_id
    description: integration ID
    in: path
    type: integer
    required: true
    x-example: 11
  extractvalue_id:
    name: extractvalue_id
    description: extractValue ID
    in: path
    type: integer
    required: true
    x-example: 12
  matcher_id:
    name: matcher_id
    description: matcher ID
    in: path
    type: integer
    required: true
    x-example: 13
  alias_id:
    name: alias_id
    description: Integration Alias ID
    in: path
    type: integer
    required: true
    x-example: 15
  invite_id:
    name: invite_id
    description: Invite ID
    in: path
    type: integer
    required: true
    x-example: 14

paths:
  /ping:
    get:
      summary: PING test
      produces:
        - text/plain
      security: []   # No security
      responses:
        200:
          description: Successful "PONG" reply
          schema:
            $ref: "#/definitions/Pong"
          headers:
            content-type:
              type: string
              x-example: text/plain; charset=utf-8

  /ws:
    get:
      summary: Websocket handler
      schemes:
        - ws
        - wss
      responses:
        200:
          description: OK
        401:
          description: not authenticated

  /info:
    get:
      summary: Fetches information about semaphore
      description: you must be authenticated to use this
      responses:
        200:
          description: ok
          schema:
            $ref: "#/definitions/InfoType"

  # Authentication
  /auth/login:
    get:
      tags:
        - authentication
      summary: Fetches login metadata
      description: Fetches metadata for login, such as available OIDC providers
      security: []
      responses:
        200:
          description: Login metadata
          schema:
            $ref: "#/definitions/LoginMetadata"
    post:
      tags:
        - authentication
      summary: Performs Login
      description: Upon success you will be logged in
      security: []   # No security
      parameters:
        - name: Login Body
          in: body
          required: true
          schema:
            $ref: '#/definitions/Login'
      responses:
        204:
          description: You are logged in
        400:
          description: something in body is missing / is invalid

  /auth/logout:
    post:
      tags:
        - authentication
      summary: Destroys current session
      responses:
        204:
          description: Your session was successfully nuked

  /auth/oidc/{provider_id}/login:
    parameters:
      - name: provider_id
        in: path
        type: string
        required: true
        x-example: "mysso"
    get:
      tags:
        - authentication
      summary: Begin OIDC authentication flow and redirect to OIDC provider
      description: The user agent is redirected to this endpoint when chosing to sign in via OIDC
      responses:
        302:
          description: Redirection to the OIDC provider on success, or to the login page on error

  /auth/oidc/{provider_id}/redirect:
    parameters:
      - name: provider_id
        in: path
        type: string
        required: true
        x-example: "mysso"
    get:
      tags:
        - authentication
      summary: Finish OIDC authentication flow, upon succes you will be logged in
      description: The user agent is redirected here by the OIDC provider to complete authentication
      responses:
        302:
          description: Redirection to the Semaphore root URL on success, or to the login page on error

  # User Tokens
  /user/:
    get:
      tags:
        - user
      summary: Fetch logged in user
      responses:
        200:
          description: User
          schema:
            $ref: "#/definitions/User"

  /user/tokens:
    get:
      tags:
        - authentication
        - user
      summary: Fetch API tokens for user
      responses:
        200:
          description: API Tokens
          schema:
            type: array
            items:
              $ref: "#/definitions/APIToken"
    post:
      tags:
        - authentication
        - user
      summary: Create an API token
      parameters:
        - name: body
          in: body
          required: false
          schema:
            type: object
            properties:
              name:
                type: string
                example: "my CI token"
      responses:
        201:
          description: API Token
          schema:
            $ref: "#/definitions/APIToken"

  /user/tokens/{api_token_id}:
    parameters:
      - name: api_token_id
        in: path
        type: string
        required: true
        x-example: "kwofd61g93-yuqvex8efmhjkgnbxlo8mp1tin6spyhu="
    delete:
      tags:
        - authentication
        - user
      summary: Expires API token
      responses:
        204:
          description: Expired API Token

  # User Profiles
  /users:
    get:
      tags:
        - user
      summary: Fetches all users
      responses:
        200:
          description: Users
          schema:
            type: array
            items:
              $ref: "#/definitions/User"
    post:
      tags:
        - user
      summary: Creates a user
      consumes:
        - application/json
      parameters:
        - name: User
          in: body
          required: true
          schema:
            $ref: "#/definitions/UserRequest"
      responses:
        400:
          description: User creation failed
        201:
          description: User created
          schema:
            $ref: "#/definitions/User"

  /users/{user_id}/:
    parameters:
      - $ref: "#/parameters/user_id"
    get:
      tags:
        - user
      summary: Fetches a user profile
      responses:
        200:
          description: User profile
          schema:
            $ref: "#/definitions/User"
    put:
      tags:
        - user
      summary: Updates user details
      consumes:
        - application/json
      parameters:
        - name: User
          in: body
          required: true
          schema:
            $ref: "#/definitions/UserPutRequest"
      responses:
        204:
          description: User Updated

    delete:
      tags:
        - user
      summary: Deletes user
      responses:
        204:
          description: User deleted

  /users/{user_id}/password:
    parameters:
      - $ref: "#/parameters/user_id"
    post:
      tags:
        - user
      summary: Updates user password
      consumes:
        - application/json
      parameters:
        - name: Password
          in: body
          required: true
          schema:
            type: object
            properties:
              password:
                type: string
                format: password
      responses:
        204:
          description: Password updated

  # Projects
  /projects:
    get:
      tags:
        - project
      summary: Get projects
      responses:
        200:
          description: List of projects
          schema:
            type: array
            items:
              $ref: "#/definitions/Project"
    post:
      tags:
        - project
      summary: Create a new project
      consumes:
        - application/json
      parameters:
        - name: Project
          in: body
          required: true
          schema:
            $ref: '#/definitions/ProjectRequest'
      responses:
        201:
          description: Created project
          schema:
            $ref: "#/definitions/Project"
  
  /projects/restore:
    post:
      tags:
        - project
      summary: Restore Project
      consumes:
        - application/json
      parameters:
        - name: Backup
          in: body
          required: true
          schema:
            $ref: '#/definitions/ProjectBackup'
      responses:
        200:
          description: Created project
          schema:
            $ref: "#/definitions/Project"

  /events:
    get:
      summary: Get Events related to Semaphore and projects you are part of
      responses:
        200:
          description: Array of events in chronological order
          schema:
            type: array
            items:
              $ref: '#/definitions/Event'
  
  /events/last:
    get:
      summary: Get last 200 Events related to Semaphore and projects you are part of
      responses:
        200:
          description: Array of events in chronological order
          schema:
            type: array
            items:
              $ref: '#/definitions/Event'

  /project/{project_id}/:
    parameters:
      - $ref: "#/parameters/project_id"
    get:
      tags:
        - project
      summary: Fetch project
      responses:
        200:
          description: Project
          schema:
            $ref: "#/definitions/Project"
    put:
      tags:
        - project
      summary: Update project
      parameters:
        - name: Project
          in: body
          required: true
          schema:
            allOf:
              - $ref: '#/definitions/ProjectRequest'
              - properties:
                  id:
                    type: integer
                    minimum: 1
      responses:
        204:
          description: Project saved
    delete:
      tags:
        - project
      summary: Delete project
      responses:
        204:
          description: Project deleted

  /project/{project_id}/backup:
    parameters:
      - $ref: "#/parameters/project_id"
    get:
      tags:
        - project
      summary: Backup A Project
      responses:
        200:
          description: Backup
          schema:
            $ref: '#/definitions/ProjectBackup'

  /project/{project_id}/role:
    parameters:
      - $ref: "#/parameters/project_id"
    get:
      tags:
        - project
      summary: Fetch permissions of the current user for project
      responses:
        200:
          description: Permissions
          schema:
            type: object
            properties:
              role:
                type: string
                example: owner
              permissions:
                type: number
                example: 0


  /project/{project_id}/events:
    parameters:
      - $ref: '#/parameters/project_id'
    get:
      tags:
        - project
      summary: Get Events related to this project
      responses:
        200:
          description: Array of events in chronological order
          schema:
            type: array
            items:
              $ref: '#/definitions/Event'

  # User management
  /project/{project_id}/users:
    parameters:
      - $ref: "#/parameters/project_id"
    get:
      tags:
        - project
      summary: Get users linked to project
      parameters:
        - name: sort
          in: query
          required: true
          type: string
          enum: [name, username, email, role]
          description: sorting name
          x-example: email
        - name: order
          in: query
          required: true
          type: string
          enum: [asc, desc]
          description: ordering manner
          x-example: desc
      responses:
        200:
          description: Users
          schema:
            type: array
            items:
              $ref: "#/definitions/ProjectUser"
    post:
      tags:
        - project
      summary: Link user to project
      parameters:
        - name: User
          in: body
          required: true
          schema:
            type: object
            properties:
              user_id:
                type: integer
                minimum: 2
              role:
                type: string
                enum: [owner, manager, task_runner, guest]
                example: owner
      responses:
        204:
          description: User added
  /project/{project_id}/users/{user_id}:
    parameters:
      - $ref: "#/parameters/project_id"
      - $ref: "#/parameters/user_id"
    delete:
      tags:
        - project
      summary: Removes user from project
      responses:
        204:
          description: User removed
    put:
      parameters:
        - name: Project User
          in: body
          required: true
          schema:
            type: object
            properties:
              role:
                type: string
                enum: [owner, manager, task_runner, guest]
                example: owner
      summary: Update user role
      tags:
        - project
      responses:
        204:
          description: User updated

  # Invite management
  /project/{project_id}/invites:
    parameters:
      - $ref: "#/parameters/project_id"
    get:
      tags:
        - project
      summary: Get invitations for project
      parameters:
        - name: sort
          in: query
          required: false
          type: string
          enum: [created, status, role]
          description: sorting field
          x-example: created
        - name: order
          in: query
          required: false
          type: string
          enum: [asc, desc]
          description: ordering manner
          x-example: desc
      responses:
        200:
          description: Project invitations
          schema:
            type: array
            items:
              $ref: "#/definitions/ProjectInvite"
    post:
      tags:
        - project
      summary: Create project invitation
      parameters:
        - name: Invite
          in: body
          required: true
          schema:
            $ref: "#/definitions/ProjectInviteRequest"
      responses:
        201:
          description: Invitation created
          schema:
            $ref: "#/definitions/ProjectInvite"
        400:
          description: Bad request (invalid role, missing user_id/email, or both provided)
        409:
          description: User already a member or invitation already exists

  /project/{project_id}/invites/{invite_id}:
    parameters:
      - $ref: "#/parameters/project_id"
      - $ref: "#/parameters/invite_id"
    get:
      tags:
        - project
      summary: Get specific project invitation
      responses:
        200:
          description: Project invitation
          schema:
            $ref: "#/definitions/ProjectInvite"
        404:
          description: Invitation not found
#    put:
#      tags:
#        - project
#      summary: Update project invitation status
#      parameters:
#        - name: Invite Update
#          in: body
#          required: true
#          schema:
#            type: object
#            properties:
#              status:
#                type: string
#                enum: [pending, declined, expired]
#                example: declined
#      responses:
#        204:
#          description: Invitation updated
#        400:
#          description: Invalid status or status transition
#    delete:
#      tags:
#        - project
#      summary: Delete project invitation
#      responses:
#        204:
#          description: Invitation deleted
#
#  /invites/accept:
#    post:
#      tags:
#        - project
#      summary: Accept project invitation
#      parameters:
#        - name: Accept Invite
#          in: body
#          required: true
#          schema:
#            $ref: "#/definitions/AcceptInviteRequest"
#      responses:
#        204:
#          description: Invitation accepted successfully
#        400:
#          description: Invalid token, invitation expired, or user already a member
#        403:
#          description: Invitation not for this user
#        404:
#          description: Invitation not found

  /project/{project_id}/integrations:
    parameters:
      - $ref: "#/parameters/project_id"
    get:
      tags:
        - integration
      summary: get all integrations
      responses:
        200:
          description: integration
          schema:
            type: array
            items:
              $ref: "#/definitions/Integration"
    post:
      summary: create a new integration
      tags:
        - integration
      parameters:
        - name: Integration
          in: body
          required: true
          schema:
            $ref: "#/definitions/IntegrationRequest"
      responses:
        201:
          description: Integration Created
          schema:
            $ref: "#/definitions/Integration"
  
  /project/{project_id}/integrations/{integration_id}:
    parameters:
      - $ref: "#/parameters/project_id"
      - $ref: "#/parameters/integration_id"
    get:
      tags:
        - integration
      summary: Get Integration
      responses:
        200:
          description: Integration Value
          schema:
            $ref: "#/definitions/Integration"
    put:
      tags:
        - integration
      summary: Update Integration
      parameters:
        - name: Integration
          in: body
          required: true
          schema:
            $ref: "#/definitions/IntegrationRequest"
      responses:
        204:
          description: Integration updated
    delete:
      tags:
        - integration
      summary: Remove integration
      responses:
        204:
          description: integration removed
  /project/{project_id}/integrations/{integration_id}/values:
    parameters:
      - $ref: "#/parameters/project_id"
      - $ref: "#/parameters/integration_id"
    get:
      tags:
        - integration
      summary: Get Integration Extracted Values linked to integration extractor
      responses:
        200:
          description: Integration Extracted Value
          schema:
            type: array
            items:
              $ref: "#/definitions/IntegrationExtractValue"
    post:
      tags:
        - integration
      summary: Add Integration Extracted Value
      parameters:
        - name: Integration Extracted Value
          in: body
          required: true
          schema:
            $ref: "#/definitions/IntegrationExtractValue"
      responses:
        201:
          description: Integration Extract Value Created
        400:
          description: Bad Integration Extract Value params
  /project/{project_id}/integrations/{integration_id}/values/{extractvalue_id}:
    parameters:
      - $ref: "#/parameters/project_id"
      - $ref: "#/parameters/integration_id"
      - $ref: "#/parameters/extractvalue_id"
    put:
      tags:
        - integration
      summary: Updates Integration ExtractValue
      parameters:
        - name: Integration ExtractValue
          in: body
          required: true
          schema:
            $ref: "#/definitions/IntegrationExtractValueRequest"
      responses:
        204:
          description: Integration Extract Value updated
        400:
          description: Bad integration extract value parameter
    delete:
      tags:
        - integration
      summary: Removes integration extract value
      responses:
        204:
          description: integration extract value removed
  /project/{project_id}/integrations/{integration_id}/matchers:
    parameters:
      - $ref: "#/parameters/project_id"
      - $ref: "#/parameters/integration_id"
    get:
      tags:
        - integration
      summary: Get Integration Matcher linked to integration extractor
      responses:
        200:
          description: Integration Matcher
          schema:
            type: array
            items:
              $ref: "#/definitions/IntegrationMatcher"
    post:
      tags:
        - integration
      summary: Add Integration Matcher
      parameters:
        - name: Integration Matcher
          in: body
          required: true
          schema:
            $ref: "#/definitions/IntegrationMatcher"
      responses:
        200:
          description: Integration Matcher Created
        400:
          description: Bad Integration Matcher params
  /project/{project_id}/integrations/{integration_id}/matchers/{matcher_id}:
    parameters:
      - $ref: "#/parameters/project_id"
      - $ref: "#/parameters/integration_id"
      - $ref: "#/parameters/matcher_id"
    put:
      tags:
        - integration
      summary: Updates Integration Matcher
      parameters:
        - name: Integration Matcher
          in: body
          required: true
          schema:
            $ref: "#/definitions/IntegrationMatcherRequest"
      responses:
        204:
          description: Integration Matcher updated
        400:
          description: Bad integration matcher parameter
    delete:
      tags:
        - integration
      summary: Removes integration matcher
      responses:
        204:
          description: integration matcher removed

  /project/{project_id}/integrations/aliases:
    parameters:
      - $ref: "#/parameters/project_id"
    get:
      tags:
        - integration
      summary: Get all integration aliases for the project
      responses:
        200:
          description: Integration Aliases
          schema:
            type: array
            items:
              $ref: "#/definitions/IntegrationAlias"
    post:
      tags:
        - integration
      summary: Create a new integration alias for the project
      responses:
        200:
          description: Integration Alias Created
          schema:
            $ref: "#/definitions/IntegrationAlias"

  /project/{project_id}/integrations/aliases/{alias_id}:
    parameters:
      - $ref: "#/parameters/project_id"
      - $ref: "#/parameters/alias_id"
    delete:
      tags:
        - integration
      summary: Remove integration alias
      responses:
        204:
          description: integration alias removed

  /project/{project_id}/integrations/{integration_id}/aliases:
    parameters:
      - $ref: "#/parameters/project_id"
      - $ref: "#/parameters/integration_id"
    get:
      tags:
        - integration
      summary: Get all aliases for an integration
      responses:
        200:
          description: Integration Aliases
          schema:
            type: array
            items:
              $ref: "#/definitions/IntegrationAlias"
    post:
      tags:
        - integration
      summary: Create a new alias for an integration
      responses:
        200:
          description: Integration Alias Created
          schema:
            $ref: "#/definitions/IntegrationAlias"

  /project/{project_id}/integrations/{integration_id}/aliases/{alias_id}:
    parameters:
      - $ref: "#/parameters/project_id"
      - $ref: "#/parameters/integration_id"
      - $ref: "#/parameters/alias_id"
    delete:
      tags:
        - integration
      summary: Remove integration alias
      responses:
        204:
          description: integration alias removed

  # project access keys
  /project/{project_id}/keys:
    parameters:
      - $ref: "#/parameters/project_id"
    get:
      tags:
        - key-store
      summary: Get access keys linked to project
      parameters:
        # TODO - the space in this parameter name results in a dredd warning
        - name: Key type
          in: query
          required: false
          type: string
          enum: [none, ssh, login_password]
          description: Filter by key type
          x-example: none
        - name: sort
          in: query
          required: true
          type: string
          enum: [name, type]
          description: sorting name
          x-example: type
        - name: order
          in: query
          required: true
          type: string
          enum: [asc, desc]
          description: ordering manner
          x-example: asc
      responses:
        200:
          description: Access Keys
          schema:
            type: array
            items:
              $ref: "#/definitions/AccessKey"
    post:
      tags:
        - key-store
      summary: Add access key
      parameters:
        - name: Access Key
          in: body
          required: true
          schema:
            $ref: "#/definitions/AccessKeyRequest"
      responses:
        201:
          description: Access Key created
          schema:
            $ref: "#/definitions/AccessKey"
        400:
          description: Bad type
  /project/{project_id}/keys/{key_id}:
    parameters:
      - $ref: "#/parameters/project_id"
      - $ref: "#/parameters/key_id"
    put:
      tags:
        - key-store
      summary: Updates access key
      parameters:
        - name: Access Key
          in: body
          required: true
          schema:
            $ref: "#/definitions/AccessKeyRequest"
      responses:
        204:
          description: Key updated
        400:
          description: Bad type
    delete:
      tags:
        - key-store
      summary: Removes access key
      responses:
        204:
          description: access key removed

  # project repositories
  /project/{project_id}/repositories:
    parameters:
      - $ref: "#/parameters/project_id"
    get:
      tags:
        - repository
      summary: Get repositories
      parameters:
        - name: sort
          in: query
          required: true
          type: string
          enum: [name, git_url, ssh_key]
          description: sorting name
        - name: order
          in: query
          required: true
          type: string
          format: asc/desc
          enum: [asc, desc]
          description: ordering manner
      responses:
        200:
          description: repositories
          schema:
            type: array
            items:
              $ref: "#/definitions/Repository"
    post:
      tags:
        - repository
      summary: Add repository
      parameters:
        - name: Repository
          in: body
          required: true
          schema:
            $ref: "#/definitions/RepositoryRequest"
      responses:
        201:
          description: Repository created
          schema:
            $ref: "#/definitions/Repository"

  /project/{project_id}/repositories/{repository_id}:
    parameters:
      - $ref: "#/parameters/project_id"
      - $ref: "#/parameters/repository_id"
    get:
      tags:
        - repository
      summary: Get repository
      responses:
        200:
          description: repository object
          schema:
            $ref: "#/definitions/Repository"
    put:
      tags:
        - repository
      summary: Updates repository
      parameters:
        - name: Repository
          in: body
          required: true
          schema:
            $ref: "#/definitions/RepositoryRequest"
      responses:
        204:
          description: Repository updated
        400:
          description: Bad request
    delete:
      tags:
        - repository
      summary: Removes repository
      responses:
        204:
          description: repository removed

  # project inventory
  /project/{project_id}/inventory:
    parameters:
      - $ref: "#/parameters/project_id"
    get:
      tags:
        - inventory
      summary: Get inventory
      parameters:
        - name: sort
          in: query
          required: true
          type: string
          description: sorting name
          enum: [name, type]
        - name: order
          in: query
          required: true
          type: string
          description: ordering manner
          enum: [asc, desc]
      responses:
        200:
          description: inventory
          schema:
            type: array
            items:
              $ref: "#/definitions/Inventory"
    post:
      tags:
        - inventory
      summary: create inventory
      parameters:
        - name: Inventory
          in: body
          required: true
          schema:
            $ref: "#/definitions/InventoryRequest"
      responses:
        201:
          description: inventory created
          schema:
            $ref: "#/definitions/Inventory"
  /project/{project_id}/inventory/{inventory_id}:
    parameters:
      - $ref: "#/parameters/project_id"
      - $ref: "#/parameters/inventory_id"
    get:
      tags:
        - inventory
      summary: Get inventory
      responses:
        200:
          description: inventory object
          schema:
            $ref: "#/definitions/Inventory"
    put:
      tags:
        - inventory
      summary: Updates inventory
      parameters:
        - name: Inventory
          in: body
          required: true
          schema:
            $ref: "#/definitions/InventoryRequest"
      responses:
        204:
          description: Inventory updated
    delete:
      tags:
        - inventory
      summary: Removes inventory
      responses:
        204:
          description: inventory removed

  # project environment
  /project/{project_id}/environment:
    parameters:
      - $ref: "#/parameters/project_id"
    get:
      tags:
        - variable-group
      summary: Get environment
      parameters:
        - name: sort
          in: query
          required: true
          type: string
          format: name
          description: sorting name
          x-example: name
        - name: order
          in: query
          required: true
          type: string
          format: asc/desc
          description: ordering manner
          x-example: desc
      responses:
        200:
          description: environment
          schema:
            type: array
            items:
              $ref: "#/definitions/Environment"
    post:
      tags:
        - variable-group
      summary: Add environment
      parameters:
        - name: environment
          in: body
          required: true
          schema:
            $ref: "#/definitions/EnvironmentRequest"
      responses:
        201:
          description: Environment created
          schema:
            $ref: "#/definitions/Environment"
  /project/{project_id}/environment/{environment_id}:
    parameters:
      - $ref: "#/parameters/project_id"
      - $ref: "#/parameters/environment_id"
    get:
      tags:
        - variable-group
      summary: Get environment
      responses:
        200:
          description: environment object
          schema:
            $ref: "#/definitions/Environment"
    put:
      tags:
        - variable-group
      summary: Update environment
      parameters:
        - name: environment
          in: body
          required: true
          schema:
            $ref: "#/definitions/EnvironmentRequest"
      responses:
        204:
          description: Environment Updated
    delete:
      tags:
        - variable-group
      summary: Removes environment
      responses:
        204:
          description: environment removed

  # project templates
  /project/{project_id}/templates:
    parameters:
      - $ref: "#/parameters/project_id"
    get:
      tags:
        - template
      summary: Get template
      parameters:
        - name: sort
          in: query
          required: true
          type: string
          description: sorting name
          enum: [name, playbook, ssh_key, inventory, environment, repository]
        - name: order
          in: query
          required: true
          type: string
          description: ordering manner
          enum: [asc, desc]
      responses:
        200:
          description: template
          schema:
            type: array
            items:
              $ref: "#/definitions/Template"
              properties:
                survey_vars:
                  type: array
                  items:
                    $ref: "#/definitions/TemplateSurveyVar"
                last_task:
                  $ref: "#/definitions/Task"
    post:
      tags:
        - template
      summary: create template
      parameters:
        - name: template
          in: body
          required: true
          schema:
            $ref: "#/definitions/TemplateRequest"
      responses:
        201:
          description: template created
          schema:
            $ref: "#/definitions/Template"
  /project/{project_id}/templates/{template_id}:
    parameters:
      - $ref: "#/parameters/project_id"
      - $ref: "#/parameters/template_id"
    get:
      tags:
        - template
      summary: Get template
      responses:
        200:
          description: template object
          schema:
            $ref: "#/definitions/Template"
    put:
      tags:
        - template
      summary: Updates template
      parameters:
        - name: template
          in: body
          required: true
          schema:
            $ref: "#/definitions/TemplateRequest"
      responses:
        204:
          description: template updated
    delete:
      tags:
        - template
      summary: Removes template
      responses:
        204:
          description: template removed

  /project/{project_id}/templates/{template_id}/stop_all_tasks:
    parameters:
      - $ref: "#/parameters/project_id"
      - $ref: "#/parameters/template_id"
    post:
      tags:
        - template
      summary: Stop all active tasks of template
      parameters:
        - name: body
          in: body
          required: false
          schema:
            type: object
            properties:
              force:
                type: boolean
                description: Force stop (kill) all tasks immediately
      responses:
        204:
          description: tasks stopped


  # project schedules
  /project/{project_id}/schedules/{schedule_id}:
    parameters:
      - $ref: "#/parameters/project_id"
      - $ref: "#/parameters/schedule_id"
    get:
      tags:
        - schedule
      summary: Get schedule
      responses:
        200:
          description: Schedule
          schema:
            $ref: "#/definitions/Schedule"
    delete:
      tags:
        - schedule
      summary: Deletes schedule
      responses:
        204:
          description: schedule deleted
    put:
      tags:
        - schedule
      summary: Updates schedule
      parameters:
        - name: schedule
          in: body
          required: true
          schema:
            $ref: "#/definitions/ScheduleRequest"
      responses:
        204:
          description: schedule updated

  /project/{project_id}/schedules:
    parameters:
      - $ref: "#/parameters/project_id"
    post:
      tags:
        - schedule
      summary: create schedule
      parameters:
        - name: schedule
          in: body
          required: true
          schema:
            $ref: "#/definitions/ScheduleRequest"
      responses:
        201:
          description: schedule created
          schema:
            $ref: "#/definitions/Schedule"

  # project views
  /project/{project_id}/views:
    parameters:
      - $ref: "#/parameters/project_id"
    get:
      tags:
        - project
      summary: Get view
      responses:
        200:
          description: view
          schema:
            type: array
            items:
              $ref: "#/definitions/View"
    post:
      tags:
        - project
      summary: create view
      parameters:
        - name: view
          in: body
          required: true
          schema:
            $ref: "#/definitions/ViewRequest"
      responses:
        201:
          description: view created
          schema:
            $ref: "#/definitions/View"
  /project/{project_id}/views/{view_id}:
    parameters:
      - $ref: "#/parameters/project_id"
      - $ref: "#/parameters/view_id"
    get:
      tags:
        - project
      summary: Get view
      responses:
        200:
          description: view object
          schema:
            $ref: "#/definitions/View"
    put:
      tags:
        - project
      summary: Updates view
      parameters:
        - name: view
          in: body
          required: true
          schema:
            $ref: "#/definitions/ViewRequest"
      responses:
        204:
          description: view updated
    delete:
      tags:
        - project
      summary: Removes view
      responses:
        204:
          description: view removed


  # tasks
  /project/{project_id}/tasks:
    parameters:
      - $ref: "#/parameters/project_id"
    get:
      tags:
        - task
      summary: Get Tasks related to current project
      responses:
        200:
          description: Array of tasks in chronological order
          schema:
            type: array
            items:
              $ref: '#/definitions/Task'
    post:
      tags:
        - task
      summary: Starts a job
      parameters:
        - name: task
          in: body
          required: true
          schema:
            type: object
            properties:
              template_id:
                type: integer
              debug:
                type: boolean
              dry_run:
                type: boolean
              diff:
                type: boolean
              playbook:
                type: string
              environment:
                type: string
              limit:
                type: string
              git_branch:
                type: string
              message:
                type: string
              arguments:
                type: string
              inventory_id:
                type: integer
      responses:
        201:
          description: Task queued
          schema:
            $ref: "#/definitions/Task"


  /project/{project_id}/tasks/last:
    parameters:
      - $ref: "#/parameters/project_id"
    get:
      tags:
        - task
      summary: Get last 200 Tasks related to current project
      responses:
        200:
          description: Array of tasks in chronological order
          schema:
            type: array
            items:
              $ref: '#/definitions/Task'


  /project/{project_id}/tasks/{task_id}/stop:
    parameters:
      - $ref: "#/parameters/project_id"
      - $ref: '#/parameters/task_id'
    post:
      tags:
        - task
      summary: Stop a job
      parameters:
        - name: body
          in: body
          required: false
          schema:
            type: object
            properties:
              force:
                type: boolean
                description: Force stop (kill) the task immediately
      responses:
        204:
          description: Task queued

  /project/{project_id}/tasks/{task_id}:
    parameters:
      - $ref: "#/parameters/project_id"
      - $ref: "#/parameters/task_id"
    get:
      tags:
        - task
      summary: Get a single task
      responses:
        200:
          description: Task
          schema:
            $ref: "#/definitions/Task"
    delete:
      tags:
        - task
      summary: Deletes task (including output)
      responses:
        204:
          description: task deleted

  /project/{project_id}/tasks/{task_id}/output:
    parameters:
      - $ref: '#/parameters/project_id'
      - $ref: '#/parameters/task_id'
    get:
      tags:
        - task
      summary: Get task output
      responses:
        200:
          description: output
          schema:
            type: array
            items:
              $ref: "#/definitions/TaskOutput"

  /project/{project_id}/tasks/{task_id}/raw_output:
    parameters:
      - $ref: '#/parameters/project_id'
      - $ref: '#/parameters/task_id'
    get:
      tags:
        - task
      summary: Get task raw output
      responses:
        200:
          description: output
          headers:
            content-type:
              type: string
              x-example: text/plain; charset=utf-8
  /apps:
    get:
      summary: Get apps
      responses:
        200:
          description: Apps
          schema:
            type: array
            items:
              $ref: "#/definitions/App"

  /project/{project_id}/notifications/test:
    post:
      tags:
        - project
      summary: Send test notification
      description: Sends a test notification to all enabled messengers for the project
      parameters:
        - $ref: "#/parameters/project_id"
      responses:
        409:
          description: Alerts not enabled for the project
#        204:
#          description: Test notification dispatched (or alerts disabled)