Skip to main content

Object Store API Reference

Management API for workspace Object Store. Base path:

https://api.pipeops.io/api/v1/workspace/{workspace_uuid}/object-store

All responses use the usual PipeOps envelope:

{ "success": true, "message": "ok", "data": { } }

For app uploads and downloads, prefer the S3 data plane with access keys — see SDK Quick Start.


Auth​

HeaderAuthorization: Bearer <pipeops_jwt_or_sa_token>
Team membersAdd ?team_uuid=<team_uuid> (required for non-owners so the workspace resolves)
RolesWorkspace owner, or team admin / member / guest
Service accountsWorkspace-scoped SA tokens work; middleware skips team membership for matching SA
export API=https://api.pipeops.io/api/v1
export TOKEN=... # PipeOps JWT or sat_* service account
export WS=... # workspace UUID
export TEAM=... # optional team UUID for members

AUTH=(-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json")
QS=""
[ -n "$TEAM" ] && QS="?team_uuid=$TEAM"
Never commit tokens

Use env vars or a secrets manager. Access key secrets are shown once at create time.


Status & URLs​

Get status​

GET /workspace/{ws}/object-store

curl -sS "${AUTH[@]}" "$API/workspace/$WS/object-store$QS" | jq .

data highlights

FieldDescription
enabledFeature enabled for the workspace
tenant_idWorkspace UUID
s3_endpointS3 API host (https://objects.pipeops.run)

Public URLs​

GET /workspace/{ws}/object-store/urls?bucket={name}

Returns public object URL helpers for a bucket (when configured).


Buckets​

List​

GET /workspace/{ws}/object-store/buckets

Create​

POST /workspace/{ws}/object-store/buckets

curl -sS "${AUTH[@]}" -X POST "$API/workspace/$WS/object-store/buckets$QS" \
-d '{"name":"my-assets"}' | jq .
Body fieldRequiredNotes
nameyesSanitized to [a-z0-9-], 3–63 chars, globally unique
encryption_modenoDefault none
location_hintnoProvider location hint when supported

Delete​

DELETE /workspace/{ws}/object-store/buckets/{name}

Soft-delete when enabled on the provider (restore window depends on config).

Soft-deleted / restore​

MethodPath
GET/buckets/deleted
POST/buckets/{name}/restore

Settings / versioning / location / lifecycle​

MethodPath
GET / PUT/buckets/{name}/settings
GET / PUT/buckets/{name}/versioning
GET/buckets/{name}/location
GET / PUT / DELETE/buckets/{name}/lifecycle

Settings may include publicDefault and cache hints used for public object URLs.

Custom domain (per bucket)​

Attach your own hostname (for example cdn.example.com) to a single bucket. Custom domains are per-bucket, not workspace-wide.

MethodPath
GET/buckets/{name}/custom-domain
PUT / POST/buckets/{name}/custom-domain
DELETE/buckets/{name}/custom-domain

You can also register from the workspace domains helper:

POST /workspace/{ws}/object-store/domains with { "hostname": "cdn.example.com", "bucket": "my-bucket" }

Steps​

  1. Create a DNS CNAME (DNS-only — do not use a TLS-terminating / orange-cloud proxy):

    cdn.example.com CNAME → <cname_target from the API>

    Prefer creating/registering the domain first if your DNS host allows a pending target, then use the cname_target returned by PipeOps. Keep the CNAME in place so TLS can issue and renew.

  2. Register the hostname on the bucket:

# Per-bucket route (console uses this)
curl -sS "${AUTH[@]}" -X PUT \
"$API/workspace/$WS/object-store/buckets/my-bucket/custom-domain$QS" \
-d '{"hostname":"cdn.example.com"}' | jq .

# Equivalent workspace helper (bucket required in body)
curl -sS "${AUTH[@]}" -X POST \
"$API/workspace/$WS/object-store/domains$QS" \
-d '{"hostname":"cdn.example.com","bucket":"my-bucket"}' | jq .

Body: { "hostname": "<fqdn>" } (alias key domain is also accepted).

Response data highlights

FieldDescription
hostnameYour custom hostname
cname_targetValue your CNAME must point to
dns_hintHuman-readable DNS instructions
urlhttps://<hostname>
statuse.g. pending after create
  1. Check status
curl -sS "${AUTH[@]}" \
"$API/workspace/$WS/object-store/buckets/my-bucket/custom-domain$QS" | jq .

curl -sS "${AUTH[@]}" \
"$API/workspace/$WS/object-store/domains/cdn.example.com/status$QS" | jq .
  1. Remove
curl -sS "${AUTH[@]}" -X DELETE \
"$API/workspace/$WS/object-store/buckets/my-bucket/custom-domain$QS" | jq .
Base URL

Use https://api.pipeops.io/api/v1/... (include /api/v1).

DNS-only

If the CNAME is proxied through a TLS terminator (for example Cloudflare orange-cloud), certificate issuance/renewal for the custom domain can fail. Use DNS-only.


Access keys​

List​

GET /workspace/{ws}/object-store/keys

Secrets are never listed—only metadata (accessKeyId, label, permissions, buckets).

Create​

POST /workspace/{ws}/object-store/keys

curl -sS "${AUTH[@]}" -X POST "$API/workspace/$WS/object-store/keys$QS" \
-d '{
"label": "ci-bot",
"permissions": ["read", "write"],
"buckets": ["my-assets"]
}' | jq .
Body fieldRequiredNotes
labelnoDefaults to dashboard
permissionsnoread, write, and/or admin. Default read+write
bucketsnoOmit or [] → all buckets (*). Otherwise only listed bucket names
Admin vs scoped buckets

Provider rule: Admin is only valid with all buckets (*). If you pass named buckets, PipeOps maps read+write (and explicit admin) to Editor on those buckets so create succeeds.

Response data (secret once)

{
"accessKeyId": "tid_...",
"secretAccessKey": "tsec_...",
"s3_endpoint": "https://objects.pipeops.run",
"region": "auto",
"tenant_id": "<workspace_uuid>",
"key": {
"accessKeyId": "tid_...",
"secretAccessKey": "tsec_...",
"permissions": ["read", "write"],
"buckets": ["my-assets"],
"label": "ci-bot"
}
}

Copy secretAccessKey immediately. Use s3_endpoint + region: auto in SDKs.

Revoke​

DELETE /workspace/{ws}/object-store/keys

curl -sS "${AUTH[@]}" -X DELETE "$API/workspace/$WS/object-store/keys$QS" \
-d '{"accessKeyId":"tid_..."}' | jq .
Policies

/keys/policy* routes exist for compatibility but IAM-style attach/detach is not implemented in the current Object Store path. Use buckets on create for scope.


Objects (management proxy)​

Useful for console/tools. Apps should prefer direct S3 with access keys.

MethodPathPurpose
GET/buckets/{name}/objects?prefix=&delimiter=/&cursor=List
POST/buckets/{name}/objectsUpload (multipart form)
POST/buckets/{name}/objects/presignGet upload URL(s)
PUT/buckets/{name}/objects/contentRaw body put
POST/buckets/{name}/objects/multipartStart multipart
PUT/buckets/{name}/objects/multipart/{uploadId}/parts/{n}Upload part
POST/buckets/{name}/objects/multipart/{uploadId}/completeComplete
DELETE/buckets/{name}/objects/multipart/{uploadId}Abort
DELETE/buckets/{name}/objects?key=Delete object
GET/buckets/{name}/objects/download?key=Download
GET/buckets/{name}/objects/versions?key=Versions
POST/buckets/{name}/foldersCreate folder prefix { "path": "dir/" }

Domains (workspace list helpers)​

MethodPath
GET/domains?bucket=
POST/domains — requires hostname + bucket (see Custom domain)
GET/domains/{hostname}/status
DELETE/domains/{hostname}

Prefer per-bucket custom-domain routes for new integrations. Both paths call the same per-bucket registration under the hood.


Public object reads (no JWT)​

When a bucket has public defaults (or the object is public):

GET https://api.pipeops.io/api/v1/public/object-store/t/{tenant_id}/objects/{key}?bucket={bucket}

Public browser URLs typically look like:

https://{bucket}.objects.pipeops.run/{key}

Errors​

HTTPTypical meaning
400Validation (bucket name, body)
401 / 403Missing/invalid auth or not a team member
404Workspace / bucket not found
409Bucket name taken / tenant not provisioned (create a bucket first)
503Object Store disabled or provider unavailable

Team members who omit team_uuid may see 404 on the workspace before membership is checked—always pass team_uuid from the active team context.


Next​

SDK Quick Start — use the access key with AWS SDK / CLI.