Skip to main content

Assets

A resource is an uploaded binary asset (today, an image) scoped to a single provider. Resources are the storage primitive behind things like branding logos and other provider-owned imagery. They decouple the stored file from the metadata that references it.

Where resources live

Each resource belongs to exactly one provider. The provider is the authorization anchor: anyone with update on the provider can upload, list, replace, patch, or delete its resources; anyone with read on the provider can stream a Resource's bytes.

Fields

FieldDescriptionExample
idUnique ID assigned at upload time5d2a91f4-8b6c-4e3a-9f12-7c8d4e5b6a01
providerIdParent provider — set on upload, immutable8b14d4f9-3a52-4b91-8e7c-d3e44b5c1f2a
nameOptional display name (up to 255 chars)acme-logo-light
contentTypeMIME type of the uploaded bytesimage/jpeg
sizeSize of the uploaded bytes, in bytes48213
ownerIdentityIdIdentity that owns the resourcec0ffee00-1111-2222-3333-444455556666
createdBy, createdAt, updatedAt, deletedAt, deletedByStandard lifecycle fields

The actual file bytes are held in internal object storage under a provider-scoped key. Clients never handle the storage key directly. They read bytes through the Customer Connect API.

Accepted content types

Only image content types are accepted at upload time:

  • image/png
  • image/gif
  • image/jpeg
  • image/webp
  • image/svg+xml

Any other Content-Type is rejected with 415 Unsupported Media Type.

Size limits

Uploads are capped at 8 MB per file.

Two ways to read a resource

1. Metadata

GET /providers/{providerId}/resources/{id} returns the resource's metadata.

2. Extension-based streaming

GET /providers/{providerId}/resources/{id}.{ext} streams the bytes through Customer Connect when the {ext} matches the stored contentType and the request's Accept header allows that type. Supported extensions: png, gif, jpg, jpeg, webp, svg.

  • If the extension doesn't map to the stored type, the response is 404 Not Found.
  • If the Accept header doesn't allow the stored type, the response is 406 Not Acceptable.

This endpoint is authorized with read (not update) on the provider, so it's safe to expose to image consumers that only need view access.

Upload

Uploads use multipart/form-data with two parts:

  • file: The binary content (required).
  • name: A display name (optional).

The providerId comes from the URL path.

Replace vs. patch

  • PUT /providers/{providerId}/resources/{id} replaces the file and name. It re-uploads the bytes to the same storage key; the resource's id and providerId are stable across replacements.
  • PATCH /providers/{providerId}/resources/{id} updates metadata only (currently just name). Send {"name": null} to clear it.

Delete

DELETE /providers/{providerId}/resources/{id} soft-deletes the metadata row and hard-deletes the stored object. The row remains in the database (with deletedAt set) for audit purposes, but the bytes are gone.

Authorization summary

OperationAuth on provider
List, get metadata, upload, replace, patch, deleteupdate
Stream bytes via /{id}.{ext}read

Resources are not independently permissioned. All decisions route through the parent provider.

More info