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

# Get

> Retrieve a file rule by its ID.



## OpenAPI

````yaml /references/device-api/v0.2.2/api.yaml get /file_rules/{file_rule_id}
openapi: 3.0.3
info:
  title: Miru Agent API
  description: >-
    The API between the Miru Agent and any external client living on the same
    device as the Miru Agent
  version: v0.2
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT
  x-release-version: v0.2.2
  x-git-commit:
    sha: 97aec4ae3541349ead148f90acedb59b0f543fdb
    url: >-
      https://github.com/mirurobotics/openapi/commit/97aec4ae3541349ead148f90acedb59b0f543fdb
    message: |-
      docs(stlc): how to change SDK custom code (#307)

      ## Why

      Hand-written SDK code goes back to stlc's intended flow (upstream docs:
      "Custom code" and "Branching and collaboration"):
      1. Edit the code in a local checkout of the staging SDK repo.
      2. Seal it with `stlc build`.
      3. Merge the tracking file through a PR here.

      A tracking file shows only two commit IDs, so the code itself needs
      somewhere to be reviewed. That's why we tried merging PRs into the
      staging repos (mirurobotics/infra#294), which stlc doesn't support.
      mirurobotics/python-device-sdk-staging#3 needed a manual re-seal (#305),
      and mirurobotics/infra#299 turns those merges off again.

      This PR documents the flow, with the review happening in a **review-only
      PR on the staging repo**.

      ## What

      New `docs/sdk-custom-code.md`, linked from the README:
      - **What custom code is:** what tracking files hold and how stlc applies
      them.
      - **Rules:**
        - nothing merges into staging `main`; PRs there are for review only;
        - prefer config over code;
        - put new code in `src/<package>/lib/`.
      - **Steps:**
        1. `stlc build` to get the local checkout.
      2. Commit on a `custom-code/<topic>` branch from staging `origin/main`,
      so the diff is only the change.
      3. Open a review-only PR on the staging repo. GitHub shows the change
      and the AI review runs.
      4. Cherry-pick the commit onto local `main` and `stlc build` to seal it.
      5. Open the tracking-file PR here, linking the staging PR, and close the
      staging PR after it lands.

      An earlier version of this PR added a CI job that commented the
      custom-code diff here. It's removed in favour of reviewing in the SDK
      repo, so the PR is now docs only.

      ## Depends on

      mirurobotics/infra#299. Until it's applied, a review PR on
      `python-device-sdk-staging` could still be merged, which is the
      situation #305 had to repair.

      🤖 Generated with [Claude Code](https://claude.com/claude-code)

      ---------

      Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
    author: ben-miru
    branch: HEAD
    dirty: false
  x-build:
    built_at: '2026-10-09T18:04:19.383464+00:00'
servers:
  - url: http://localhost/v0.2
    description: localhost
security:
  - {}
  - BearerAuth: []
paths:
  /file_rules/{file_rule_id}:
    get:
      tags:
        - File Rules
      summary: Get
      description: Retrieve a file rule by its ID.
      operationId: getFileRule
      parameters:
        - $ref: '#/components/parameters/file_rule_id'
      responses:
        '200':
          description: Successfully retrieved the file rule.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BaseFileRule'
      x-codeSamples:
        - lang: curl
          label: curl (Linux)
          source: |-
            curl \
              --unix-socket /run/miru/miru.sock \
              --request GET \
              --url http://localhost/v0.2/file_rules/{file_rule_id}
        - lang: powershell
          label: PowerShell (Windows)
          source: >-
            $api = Get-Content -Raw
            "$env:ProgramData\Miru\device-api\device-api.json" |
            ConvertFrom-Json; `

            Invoke-RestMethod -Method Get `
              -Uri "http://127.0.0.1:$($api.port)/v0.2/file_rules/{file_rule_id}" `
              -Headers @{ Authorization = "Bearer $($api.token)" }
        - lang: Python
          source: |-
            from miru_device_sdk import Miru

            client = Miru()
            file_rule = client.file_rules.retrieve(
                "file_rule_123",
            )
            print(file_rule.id)
components:
  parameters:
    file_rule_id:
      name: file_rule_id
      in: path
      required: true
      description: The unique identifier of the file rule.
      schema:
        type: string
        example: file_rule_123
  schemas:
    BaseFileRule:
      title: Base File Rule
      type: object
      description: |
        A file rule declares which files on a device Miru manages and what to do
        with them: upload them to a bucket, delete the local copies once they
        are no longer needed, or both. `retention` is optional and marks the
        rules that delete: when it is absent the device keeps matching files
        indefinitely — Miru never deletes them — and when it is present the rule
        deletes each matching file once its retention guarantee ends. A rule
        that both deletes and uploads always states `retention.require_upload`,
        so whether local deletion waits for the upload is itself an explicit
        decision.
      required:
        - object
        - id
        - name
        - digest
        - os
        - source
        - created_at
        - updated_at
      properties:
        object:
          type: string
          enum:
            - file_rule
          example: file_rule
          x-stainless-const: true
          description: The object type, which is always `file_rule`.
        id:
          type: string
          example: file_rule_123
          description: ID of the file rule.
        name:
          type: string
          example: Robot Logs
          description: >-
            A human-readable name for the file rule. Not unique within a
            workspace: file rules are immutable, so each authored revision mints
            a new rule and several rules may share a name. The name participates
            in the rule's digest, so renaming a rule mints a new rule.
        digest:
          type: string
          example: sha256:1234567890
          description: >-
            The digest of the file rule. File rules are immutable and
            deduplicated by digest within a workspace.
        os:
          allOf:
            - $ref: '#/components/schemas/OS'
          readOnly: true
          description: >-
            The operating system family this file rule targets, derived from
            `source.glob`: a glob starting with `/` is `linux`, and a glob
            starting with a drive letter is `windows`. Read-only: clients cannot
            set it.
        source:
          $ref: '#/components/schemas/FileRuleSource'
        upload:
          allOf:
            - $ref: '#/components/schemas/FileRuleUpload'
          description: >-
            Where matching files are uploaded. Absent when the rule only
            enforces local retention.
        retention:
          allOf:
            - $ref: '#/components/schemas/FileRuleRetention'
          description: >-
            Governs deletion of the local copies of matching files. Absent when
            the device keeps matching files indefinitely — Miru never deletes
            them; present when the rule deletes each matching file once its
            retention guarantee ends.
        created_at:
          type: string
          format: date-time
          example: '2021-01-01T00:00:00Z'
          description: Timestamp of when the file rule was created.
        updated_at:
          type: string
          format: date-time
          example: '2021-01-01T00:00:00Z'
          description: Timestamp of when the file rule was last updated.
      example:
        object: file_rule
        id: file_rule_123
        name: Robot Logs
        digest: sha256:1234567890
        os: linux
        source:
          glob: /var/log/robot/*.log
          stability_window_secs: 60
        upload:
          upload_collection_id: upl_col_123
          upload_collection_name: Robot Logs
          bucket_id: bkt_123
          bucket_name: my-uploads-bucket
          path: '{device_id}/{year}-{month}-{day}/{upload_id}/{file_name}'
        retention:
          require_upload: true
          ttl_secs: 604800
        created_at: '2021-01-01T00:00:00Z'
        updated_at: '2021-01-01T00:00:00Z'
    OS:
      title: OS
      type: string
      description: >
        An operating system family, from the agent's build-time OS vocabulary.
        Shared across resources (devices, config schemas, file rules, releases).
        This is the machine-readable OS kind, distinct from a human-readable
        version string.

        - `linux`

        - `windows`
      example: linux
      enum:
        - linux
        - windows
      x-enum-varnames:
        - OS_LINUX
        - OS_WINDOWS
    FileRuleSource:
      title: File Rule Source
      type: object
      required:
        - glob
        - stability_window_secs
      properties:
        glob:
          type: string
          pattern: ^(/|[A-Za-z]:[\\/])
          maxLength: 1024
          example: /var/log/robot/*.log
          description: >-
            A glob pattern selecting the files this rule manages. Must be
            absolute (start with `/` on Linux, or a drive letter followed by
            `:\` or `:/` on Windows, e.g. `C:\logs\*.log`), at most 1024 bytes,
            and must contain no `..` segments and no empty path segments.
        stability_window_secs:
          type: integer
          format: int64
          example: 60
          description: >-
            How long, in seconds, a matching file's size and modification time
            must stay unchanged (quiescent) before it is considered finished and
            eligible for upload. Files in a format with a finalization marker
            (e.g. MCAP, parquet) are detected directly; this window is the
            fallback for other files.
      example:
        glob: /var/log/robot/*.log
        stability_window_secs: 60
    FileRuleUpload:
      title: File Rule Upload
      type: object
      required:
        - upload_collection_id
        - upload_collection_name
        - bucket_id
        - bucket_name
        - path
      properties:
        upload_collection_id:
          type: string
          example: upl_col_123
          description: ID of the upload collection the resulting uploads are grouped into.
        upload_collection_name:
          type: string
          example: Robot Logs
          description: >-
            The name of the upload collection the resulting uploads are grouped
            into.
        bucket_id:
          type: string
          example: bkt_123
          description: ID of the bucket this rule uploads to.
        bucket_name:
          type: string
          example: my-uploads-bucket
          description: Name of the bucket this rule uploads to.
        path:
          type: string
          pattern: .*\{upload_id\}.*
          maxLength: 1024
          example: '{device_id}/{year}-{month}-{day}/{upload_id}/{file_name}'
          description: >-
            The object-path template the collected file is written to. Must
            contain `{upload_id}` so every upload lands on a distinct object
            key, be at most 1024 bytes, have balanced braces, and contain no
            `..` segments and no empty path segments. The supported variables
            are `{device_id}`, `{device_name}`, `{file_name}`, `{upload_id}`,
            `{year}`, `{month}`, `{day}`, `{hour}`, and `{minute}`.
      example:
        upload_collection_id: upl_col_123
        upload_collection_name: Robot Logs
        bucket_id: bkt_123
        bucket_name: my-uploads-bucket
        path: '{device_id}/{year}-{month}-{day}/{upload_id}/{file_name}'
    FileRuleRetention:
      title: File Rule Retention
      type: object
      description: |
        The retention block a file rule carries when it deletes local files; a
        rule without one keeps matching files indefinitely and Miru never
        deletes them. Retention operates in two phases. The retention guarantee
        ends once a matching file goes quiescent — its size and modification
        time have stayed unchanged for `source.stability_window_secs` — and,
        when `require_upload` is `true`, once its upload has been durably
        confirmed; the file is then eligible for deletion, and callers may no
        longer rely on it being present. `ttl_secs` schedules the enforcement
        that follows: how long the file lives on after the guarantee ends
        before the device deletes it. Both phases keep running on the device
        even when no release is deployed, so tearing down a deployment does not
        silently stop reclaiming disk.
      required:
        - ttl_secs
      properties:
        require_upload:
          type: boolean
          example: true
          description: >-
            Whether a file must have its upload durably confirmed before it may
            be deleted. Present exactly when the rule has an `upload` block.
            When `true`, a slow or failing upload keeps the local file: the
            device abandons an upload after 9 attempts, so a permanently failing
            upload retains the file indefinitely. When `false`, the upload is
            best-effort: the file may be deleted once eligible even if its
            upload has not completed, and an unfinished upload is abandoned.
        ttl_secs:
          type: integer
          format: int64
          example: 604800
          description: >-
            How long, in seconds, the file lives on after it becomes eligible
            for deletion. The clock starts when the retention guarantee ends,
            not when the file was written: this schedules enforcement of a
            guarantee that has already ended, so it defers the deletion, not the
            end of the guarantee. `0` means the file is deleted as soon as it
            becomes eligible.
      example:
        require_upload: true
        ttl_secs: 604800
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: >-
        The token from the agent's discovery file. Required over loopback TCP;
        not used over the Unix socket.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.