# How-to: manage Orchestrator resources

> Daily tasks for managing Orchestrator resources with `uip resource`, covering assets, buckets, libraries, queues, triggers, and webhooks.

The [`uip resource`](./uip-resource.md) tool is the general-purpose CRUD surface over Orchestrator's runtime resources: **assets, buckets (and files inside them), libraries, queues (and items), triggers, and webhooks**. This page collects the tasks that come up daily — bulk-creating assets, moving files in and out of buckets, dispatching queue work, inspecting triggers — as copy-pasteable snippets.

The full flag list for every subcommand is on the [`uip resource`](./uip-resource.md) reference page. This page covers the common usage patterns.

:::note
`uip resource` is different from `uip solution resource`. The former is the CRUD surface on Orchestrator (this page). The latter inspects **local** resource declarations inside a `.uipx` solution. If in doubt, look at the prefix: `uip solution resource …` only ever reads your disk; `uip resource …` always calls Orchestrator.
:::

## Conventions you need to know first

Before any snippet works:

- **Authentication.** Every `uip resource` verb calls Orchestrator. Run [`uip login`](./authentication.md) first. Pass `--tenant <name>` (short `-t`) on any verb to override the session tenant for a single call.
- **Folder scoping.** Assets, buckets, queues, queue items, and time/queue triggers are **folder-scoped** — pass `--folder-path` (e.g. `Shared`) or `--folder-key` (GUID). Libraries, API triggers, and webhooks are **tenant-scoped** and reject the folder flags.
- **Keys.** List verbs return GUIDs (`key`, `identifier`, `uniqueKey`). Pass those to `get`, `update`, and `delete`. Numeric `id` fields are internal; do not pass them to commands.
- **JSON is the default output.** Every snippet below relies on this; see [Output formats](./output-formats.md).

## Assets

### Bulk-deploy assets from a CSV

This is the most common "manage my secrets and config" task. Given a CSV like:

```csv
name,value,type,folderPath
ApiEndpoint,https://api.example.com,Text,Shared
MaxRetries,3,Integer,Shared
Debug,false,Bool,Shared
```

Loop over it with plain bash + `uip resource assets create`:

```bash
#!/usr/bin/env bash
set -euo pipefail

# Skip the header row
tail -n +2 ./assets.csv | while IFS=, read -r name value type folder; do
  uip resource assets create "$name" "$value" \
    --folder-path "$folder" \
    --type "$type"
done
```

Re-running this against the same folder will fail on duplicates. Two ways to handle that:

- **Upsert pattern.** List first, then `create` or `update` per row:

  ```bash
  tail -n +2 ./assets.csv | while IFS=, read -r name value type folder; do
    existing=$(uip resource assets list --folder-path "$folder" --name "$name" \
      --output-filter "Data[?name=='$name'] | [0].key" --output plain)

    if [ -n "$existing" ] && [ "$existing" != "null" ]; then
      uip resource assets update "$existing" "$value"
    else
      uip resource assets create "$name" "$value" --folder-path "$folder" --type "$type"
    fi
  done
  ```

- **Solution deploy pattern.** For asset sets that ship alongside a package, declare them in the Solution manifest and use [`uip solution deploy run --config-file`](./uip-solution-deploy.md#uip-solution-deploy-run) — that path is idempotent by design. See [How-to: pack and publish a Solution](./howto-pack-publish-solution.md).

### Credential-type assets

Credential and secret assets need a credential-store key:

```bash
# Find the credential store
STORE_KEY=$(uip or credential-stores list \
  --output-filter "Data[?name=='MyStore'] | [0].key" --output plain)

# Create the credential asset (value format: username:password)
uip resource assets create ApiLogin "alice:s3cr3t" \
  --folder-path Shared \
  --type Credential \
  --credential-store-key "$STORE_KEY"
```

Credential and secret values are **never returned** by `list` or `get`; use [`assets get-asset-value`](./uip-resource-assets.md#get-asset-value) (which still needs a folder scope) to read the live value, or call through the robot.

### Sharing assets across folders

Create once in `Shared`, then share to each folder that needs it:

```bash
ASSET_KEY=$(uip resource assets list --folder-path Shared --name ApiEndpoint \
  --output-filter "Data[0].key" --output plain)

for folder in Production Staging Development; do
  uip resource assets share "$ASSET_KEY" --folder-path "$folder"
done
```

Revoke with `unshare`. See [Assets](./uip-resource-assets.md) for the full verb list.

## Buckets and bucket files

### Upload a local file

```bash
BUCKET_KEY=$(uip resource buckets list --folder-path Shared \
  --output-filter "Data[?name=='invoices'] | [0].key" --output plain)

uip resource bucket-files write "$BUCKET_KEY" "inbox/invoice-001.pdf" \
  --folder-path Shared \
  --file ./invoice-001.pdf
```

The path inside the bucket (`inbox/invoice-001.pdf`) is the second argument to `write`; `--file` is the local path to upload. Content type is auto-detected; pass `--content-type` to override.

### Download a file

```bash
uip resource bucket-files read "$BUCKET_KEY" "reports/summary.csv" \
  --folder-path Shared \
  --destination ./summary.csv
```

Without `--destination`, the content is streamed to stdout — useful for piping into a processor.

### List and paginate

```bash
# First page
uip resource bucket-files list "$BUCKET_KEY" --folder-path Shared

# The response carries a continuationToken — pass it back to fetch the next page
uip resource bucket-files list "$BUCKET_KEY" --folder-path Shared \
  --continuation-token "<token-from-previous-response>"
```

Bucket file listings are the one resource in the CLI that uses a continuation token rather than offset pagination — the other list verbs take `--limit` / `--offset`.

### Pre-signed URLs

If a robot or external service needs direct blob access without going through the CLI:

```bash
uip resource bucket-files get-upload-url "$BUCKET_KEY" "inbox/incoming.pdf" \
  --folder-path Shared --expiry-in-minutes 30

uip resource bucket-files get-download-url "$BUCKET_KEY" "reports/summary.csv" \
  --folder-path Shared --expiry-in-minutes 30
```

Both return a time-limited URL scoped to the single file path.

## Queues and queue items

### Create a queue

```bash
uip resource queues create InvoiceQueue \
  --folder-path Shared \
  --max-retries 3 \
  --retention-period 90
```

Full flag list — `--auto-retry`, `--enforce-unique-reference`, `--encrypted`, retention settings — on the [queues reference](./uip-resource-queues.md).

### Add a single work item

```bash
uip resource queue-items add InvoiceQueue \
  --folder-path Shared \
  --specific-content '{"InvoiceId":"INV-001","Amount":1500}' \
  --priority High
```

`--specific-content` is the JSON payload the robot will read.

### Bulk-add from a file

```bash
cat > ./items.json <<'EOF'
[
  {"Name": "InvoiceQueue", "Priority": "Normal", "SpecificContent": {"InvoiceId":"INV-001"}},
  {"Name": "InvoiceQueue", "Priority": "Normal", "SpecificContent": {"InvoiceId":"INV-002"}}
]
EOF

ITEMS=$(jq -c . ./items.json)
uip resource queue-items bulk-add InvoiceQueue \
  --folder-path Shared \
  --queue-items "$ITEMS" \
  --commit-type StopOnFirstFailure
```

`--commit-type` controls what happens when one row fails validation: `ProcessAllIndependently` (default), `StopOnFirstFailure`, or `AllOrNothing`.

### Inspect failed items

```bash
uip resource queue-items list --folder-path Shared \
  --queue-name InvoiceQueue \
  --status Failed \
  --output-filter "Data[].{key:uniqueKey, ref:reference, reason:processingException}"
```

Use [`queue-items get-history`](./uip-resource-queue-items.md#get-history) on a single `uniqueKey` to see its full state transition history — useful for diagnosing retry loops.

### Mark failed items for retry

```bash
uip resource queue-items set-review-status Retried \
  "<queue-item-key-1>" "<queue-item-key-2>"
```

`set-review-status` takes one of `Retried`, `Abandoned`, `Deleted`.

## Triggers

### List triggers in a folder

```bash
uip resource triggers list --type time --folder-path Shared --enabled \
  --output-filter "Data[].{name:name, cron:startProcessCron, enabled:isEnabled}"
```

Three trigger types: `time`, `queue`, and `api`. Pass `--type` on every verb (it defaults to `time`). API triggers are tenant-scoped — omit `--folder-path`.

### Create a time trigger

```bash
RELEASE_KEY=$(uip or processes list --folder-path Shared --name InvoiceProcessing \
  --output-filter "Data[0].Key" --output plain)

uip resource triggers create --type time \
  --name NightlyInvoices \
  --release-key "$RELEASE_KEY" \
  --runtime-type Unattended \
  --job-priority Normal \
  --folder-path Shared \
  --cron "0 0 2 * * ?" \
  --time-zone UTC
```

The `--cron` value uses Quartz's 6-field format (`sec min hour dayOfMonth month dayOfWeek`), **not** standard cron. `"0 0 2 * * ?"` is "every day at 02:00".

### Enable or disable a trigger

```bash
uip resource triggers enable <trigger-key> --type time --folder-path Shared
uip resource triggers disable <trigger-key> --type time --folder-path Shared
```

Use [`triggers history`](./uip-resource-triggers.md#history) to diagnose a trigger that isn't firing — the fire log surfaces missing licenses, unavailable machines, and other upstream blocks.

## Webhooks

Webhooks are tenant-scoped. Create once, and the webhook fires on every matching event in the tenant:

```bash
uip resource webhooks create --name JobAlerts \
  --url https://hooks.example.com/uipath \
  --events "job.completed,job.faulted" \
  --secret "$WEBHOOK_SECRET"
```

List available event types for a tenant:

```bash
uip resource webhooks event-types
```

Test delivery without waiting for a real event:

```bash
uip resource webhooks ping <webhook-key>
```

## Libraries

Libraries are tenant-scoped (not folder-scoped) — they live in the tenant feed and are referenced by package IDs like `MyLib:1.0.0`:

```bash
# Upload a new version
uip resource libraries upload --file ./MyLib.1.0.0.nupkg

# See all versions of a package
uip resource libraries versions MyLib

# Download a specific version
uip resource libraries download MyLib:1.0.0 --destination ./MyLib.1.0.0.nupkg
```

Keys take the form `PackageId:Version` — not a GUID.

## Scripting tips

- **Always pass `--output-filter` when feeding a single value into a variable.** It avoids brittle `jq` invocations and validates at CLI-parse time — see [Scripting patterns](./scripting-patterns.md#reading-values-out-of-the-envelope).
- **List verbs return paginated results** — `--limit` / `--offset` on most, `--continuation-token` on bucket files. Empty results (zero rows in `Data`) still exit `0` — the list query succeeded; nothing matched.
- **Most update/delete verbs are cross-folder** — the flag table on each verb's section of [`uip resource`](./uip-resource.md) says so explicitly ("Cross-folder"). Only `create` and list need the folder scope on those resources.

## See also

- **[`uip resource` reference](./uip-resource.md)** — the authoritative verb-by-verb flag list. Every snippet on this page links back to the matching section.
- **[`uip solution deploy config link`](./uip-solution-deploy.md#uip-solution-deploy-config-link)** — bind a Solution's declared resource to one you created with `uip resource`.
- **[Scripting patterns](./scripting-patterns.md)** — polling, retry on exit `2`, idempotent pipelines.
- **[How-to: pack and publish a Solution](./howto-pack-publish-solution.md)** — the alternative path for resources that ship with a package.
