Skip to main content

Find, browse, copy, and move objects

Find and rearrange files: list with filters, browse as folders, search, and copy or move. Choose an interface below. REST examples use a server-side API key; keep it out of browser code.

Configure client with the JavaScript SDK setup or the synchronous Python client setup. For Refine, register the named storage provider and initialize these hooks inside a React component or custom hook under <Refine>. Browser examples use the signed-in user session; keep API keys in server code. Replace BUCKET_SLUG with your bucket slug.

List and filter#

The list endpoint accepts a rich filter grammar. Every parameter is optional. Both SDKs return objects in the response’s data field and their count in total.

Return only PDFs in a folder, largest first:

import {Storage} from '@taruvi/sdk';
import type {StorageListResponse} from '@taruvi/sdk';

await new Storage(client).from('BUCKET_SLUG')
.filter({prefix: 'reports/', mimetype: 'application/pdf', ordering: '-size', page_size: 50}).execute<StorageListResponse>();

Return objects the caller created since a date:

import {Storage} from '@taruvi/sdk';
import type {StorageListResponse} from '@taruvi/sdk';

await new Storage(client).from('BUCKET_SLUG')
.filter({created_by_me: true, created_after: '2026-09-01'}).execute<StorageListResponse>();

Search filename or path substring:

import {Storage} from '@taruvi/sdk';
import type {StorageListResponse} from '@taruvi/sdk';

await new Storage(client).from('BUCKET_SLUG')
.filter({search: 'invoice'}).execute<StorageListResponse>();

Combine visibility with pagination:

import {Storage} from '@taruvi/sdk';
import type {StorageListResponse} from '@taruvi/sdk';

await new Storage(client).from('BUCKET_SLUG')
.filter({visibility: 'public', page: 2, page_size: 50, ordering: '-created_at'}).execute<StorageListResponse>();

Refine combines these filters with AND. Use operator: 'eq' for named query parameters such as search or prefix.

The full filter grammar — range filters, MIME categories, path lookups, ordering — is on the Filter grammar reference.

Browse as folders#

GET /objects/browse/ treats paths as folders and returns one level at a time. It requires sign-in, even for public buckets.

import {Storage} from '@taruvi/sdk';
import type {StorageBrowseResponse} from '@taruvi/sdk';

await new Storage(client).from('BUCKET_SLUG').browse({
prefix: 'documents/2024/', sort: 'name', order: 'asc', page: 1, page_size: 50,
}).execute<StorageBrowseResponse>();

The response’s data contains folders, objects, and has_next.

Response body:

{
"status": "success",
"message": "…",
"data": {
"prefix": "documents/2024/",
"folders": [{ "type": "folder", "name": "Q1", "path": "documents/2024/Q1/" }],
"objects": [{
"type": "file", "id": 1, "uuid": "…", "name": "report.pdf",
"path": "documents/2024/report.pdf", "size": 12345, "mimetype": "application/pdf",
"visibility": "private", "is_office_editable": false,
"created_at": "…", "updated_at": "…", "download_url": "…"
}],
"page": 1, "page_size": 50, "has_next": false
}
}

Navigate deeper by passing a folder's path back as prefix. Sort field is one of name, size, created_at, updated_at; order is asc or desc. page_size is bounded at 100.

POST /objects/search/ accepts a JSON body for structured filtering with a bounded result limit.

POST/api/apps/APP_SLUG/storage/buckets/BUCKET_SLUG/objects/search/

Authorization
Api-Key $TARUVI_API_KEY
Content-Type
application/json
{
"prefix": "users/123/",
"search": "profile",
"sortBy": {
"column": "created_at",
"order": "desc"
},
"limit": 100,
"offset": 0
}
View cURL
curl --silent --show-error -X POST "$TARUVI_SITE_URL/api/apps/APP_SLUG/storage/buckets/BUCKET_SLUG/objects/search/" \
-H "Authorization: Api-Key $TARUVI_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'JSON'
{
"prefix": "users/123/",
"search": "profile",
"sortBy": {
"column": "created_at",
"order": "desc"
},
"limit": 100,
"offset": 0
}
JSON

200

limit defaults to 100; a value above 1000 is rejected with 400. sortBy.column is one of filename, size, created_at, updated_at, path, mimetype; any other value falls back to created_at. The response envelope contains objects (the list) and bucket (the slug); total rides on the envelope.

Copy an object#

Copy leaves the source in place and creates a new object at the destination. Same-app operation — the destination bucket must live under the same app_slug as the source.

client.storage.from_("BUCKET_SLUG").copy_object(
"users/user-123/avatar.png",
"users/user-123/avatar.png",
destination_bucket="user-thumbnails",
)

user-thumbnails is an existing destination bucket in the same app. The result is the copied object.

destination_bucket is optional and defaults to the current bucket. Copy returns 201 Created. The caller needs read access to the source and upload access to the destination.

Move or rename#

Move rewrites the object. Same-bucket moves become a path rename; cross-bucket moves copy then delete.

Rename in place:

client.storage.from_("BUCKET_SLUG").move_object(
"temp/upload-1234.pdf",
"invoices/2024/Q3/INV-1234.pdf",
)

Move to a different bucket in the same app:

POST/api/apps/APP_SLUG/storage/buckets/BUCKET_SLUG/objects/move/

Authorization
Api-Key $TARUVI_API_KEY
Content-Type
application/json
{
"source_path": "drafts/report.docx",
"destination_bucket": "published-reports",
"destination_path": "2024/Q3/report.docx"
}
View cURL
curl --silent --show-error -X POST "$TARUVI_SITE_URL/api/apps/APP_SLUG/storage/buckets/BUCKET_SLUG/objects/move/" \
-H "Authorization: Api-Key $TARUVI_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'JSON'
{
"source_path": "drafts/report.docx",
"destination_bucket": "published-reports",
"destination_path": "2024/Q3/report.docx"
}
JSON

200

Move failure modes:

  • 409 Conflict — destination path is occupied. Rename the source or clear the destination first.
  • 400 with "Cross-provider move is not supported" — source and destination buckets use different storage_provider values. Download the object, upload it to the target bucket, and delete the source separately.
  • 404 with "Source object 'PATH' not found" — the source_path does not match any object in the resolved source bucket.

Moving within a bucket needs update access. Moving to another bucket needs delete access on the source and upload access on the destination.