> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getprimo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Run a script on one device

> Run a script on the device for the given device ID. Pass `{ "scriptId": 12 }` to run a saved script (see `getScripts`), or `{ "contents": "..." }` to send the source inline.

This is the single-device shortcut for `runScript`; use that one to target all devices, device groups, or several devices at once. The platforms are derived from the device, so a script whose interpreter does not match it is rejected.

The response returns immediately with the execution `pending`; poll `getDeviceScriptExecutions` or `getScriptRun` for the outcome.

⚠️ **This executes arbitrary code on the device with elevated privileges, and is not idempotent** — repeating the call runs the script again. Review the script before calling.

**Supported platforms:** macOS (shell/Python), Windows (PowerShell), Linux (shell/Python). Not supported: iOS, Android, ChromeOS.

<span className="badge-write">Key: Write</span><span className="badge-company">Scope: Company</span>


## OpenAPI

````yaml https://api.getprimo.com/openapi.json post /devices/{deviceId}/run-script
openapi: 3.1.1
info:
  title: Public API - BETA
  description: Read docs on https://docs.getprimo.com/
  version: '1.0'
  contact: {}
servers:
  - url: https://api.getprimo.com
security:
  - apikey: []
tags: []
paths:
  /devices/{deviceId}/run-script:
    post:
      tags:
        - Devices
      summary: Run a script on one device
      description: >-
        Run a script on the device for the given device ID. Pass `{ "scriptId":
        12 }` to run a saved script (see `getScripts`), or `{ "contents": "..."
        }` to send the source inline.


        This is the single-device shortcut for `runScript`; use that one to
        target all devices, device groups, or several devices at once. The
        platforms are derived from the device, so a script whose interpreter
        does not match it is rejected.


        The response returns immediately with the execution `pending`; poll
        `getDeviceScriptExecutions` or `getScriptRun` for the outcome.


        ⚠️ **This executes arbitrary code on the device with elevated
        privileges, and is not idempotent** — repeating the call runs the script
        again. Review the script before calling.


        **Supported platforms:** macOS (shell/Python), Windows (PowerShell),
        Linux (shell/Python). Not supported: iOS, Android, ChromeOS.
      operationId: runDeviceScript
      parameters:
        - name: deviceId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RunDeviceScriptBody'
      responses:
        default:
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RunScript_Output'
components:
  schemas:
    RunDeviceScriptBody:
      type: object
      properties:
        script:
          description: >-
            What to run: `{ "scriptId": 12 }` for a script from the catalog, or
            `{ "contents": "..." }` to send the source inline. An inline run may
            only target a single device.
          anyOf:
            - type: object
              properties:
                scriptId:
                  type: integer
                  exclusiveMinimum: 0
                  maximum: 9007199254740991
              required:
                - scriptId
            - type: object
              properties:
                contents:
                  type: string
                  minLength: 1
                  maxLength: 10000
              required:
                - contents
      required:
        - script
    RunScript_Output:
      type: object
      properties:
        id:
          type: string
        script:
          type: object
          properties:
            scriptId:
              description: >-
                Saved script that was run, or null when the contents were sent
                inline.
              anyOf:
                - type: number
                - type: 'null'
            name:
              description: Script name at the time of the run. Null for an inline run.
              anyOf:
                - type: string
                - type: 'null'
          required:
            - scriptId
            - name
          additionalProperties: false
        target:
          description: The target as submitted.
          anyOf:
            - type: object
              properties:
                type:
                  type: string
                  const: all
              required:
                - type
              additionalProperties: false
            - type: object
              properties:
                type:
                  type: string
                  const: deviceGroups
                deviceGroupIds:
                  minItems: 1
                  type: array
                  items:
                    type: string
              required:
                - type
                - deviceGroupIds
              additionalProperties: false
            - type: object
              properties:
                type:
                  type: string
                  const: devices
                deviceIds:
                  minItems: 1
                  type: array
                  items:
                    type: string
              required:
                - type
                - deviceIds
              additionalProperties: false
        platforms:
          type: array
          items:
            type: string
            enum:
              - macos
              - windows
              - linux
        contents:
          type: string
          description: Full source of the script as executed.
        totalExecutions:
          type: number
          description: Number of devices the run resolved to.
        createdAt:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
        executions:
          type: array
          description: >-
            One execution per resolved device, all `pending` at creation. Poll
            `getScriptRun` or `getScriptRunExecutions` for outcomes.
          items:
            type: object
            properties:
              id:
                type: string
              runId:
                description: Identifier of the script run this execution belongs to.
                type: string
              deviceId:
                type: string
              status:
                description: >-
                  Outcome on one device. `pending`: queued, the device may be
                  offline. `success`: ran with exit code 0. `failed`: ran with a
                  non-zero exit code, or the device was incompatible. `timeout`:
                  exceeded the execution limit. `cancelled`: cancelled before
                  running.
                type: string
                enum:
                  - pending
                  - success
                  - failed
                  - timeout
                  - cancelled
              output:
                description: >-
                  Combined stdout/stderr once the execution completes. Null
                  while pending.
                anyOf:
                  - type: string
                  - type: 'null'
              exitCode:
                description: >-
                  Process exit code once the execution completes. Null while
                  pending.
                anyOf:
                  - type: number
                  - type: 'null'
              runtime:
                description: >-
                  Duration in seconds once the execution completes. Null while
                  pending.
                anyOf:
                  - type: number
                  - type: 'null'
              createdAt:
                type: string
                format: date-time
                pattern: >-
                  ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
              updatedAt:
                type: string
                format: date-time
                pattern: >-
                  ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
            required:
              - id
              - runId
              - deviceId
              - status
              - output
              - exitCode
              - runtime
              - createdAt
              - updatedAt
            additionalProperties: false
      required:
        - id
        - script
        - target
        - platforms
        - contents
        - totalExecutions
        - createdAt
        - executions
      additionalProperties: false
  securitySchemes:
    apikey:
      scheme: bearer
      bearerFormat: API key
      type: http
      description: >-
        Use your Primo API key in the Authorization header as `Bearer
        <API_KEY>`.

````