Skip to main content
Developers can configure Daily to store call recordings and transcripts in an Oracle Cloud Infrastructure (OCI) Object Storage bucket of their choice. As with custom S3 storage, Daily does not store the recording on its own servers at any point — files are written directly into the specified bucket.
OCI storage is not self-serve. Unlike an S3 bucket, you cannot finish this setup on your own through the REST API. Daily has to provision credentials on its side before your bucket will accept writes, and you need an identifier from Daily before you can write your access policy.To get started, email support@daily.co with the details in step 1 below.
If you’re new to call recording with Daily, check out the recording guide first.

Why OCI setup differs from S3

With S3, Daily calls AWS STS AssumeRole against a role you create, using your Daily domain as the external ID. AWS issues Daily short-lived credentials scoped to that role at the moment a recording starts. Everything Daily needs arrives in the API request, so you can complete the whole setup yourself. OCI has no equivalent. Cross-tenancy access in OCI is granted through Endorse and Admit policy statements, which authorize an existing principal rather than issuing a new credential for it — Oracle’s documentation is explicit that the caller uses “the credentials as usual from the endorsing (source) tenancy.” On top of that, Daily writes objects through OCI’s Amazon S3 Compatibility API, whose only supported authentication is a Customer Secret Key — a static access key and secret key pair, which per Oracle “don’t expire.” There is no session-token header, so even a short-lived credential could not be used on this path. The practical consequence is that Daily provisions and holds the credentials on its side, per domain. Oracle also requires that “both tenancies must agree on access”: Daily writes its half of the policy inside Daily’s tenancy, and you write yours. That exchange is what makes this a support conversation rather than an API call.

Setup process

Step 1: Send Daily your bucket details

Email support@daily.co with:

Step 2: Daily provisions its side

Daily creates the principal that will write to your bucket and stores its credentials against your domain. Nothing is required from you during this step.

Step 3: Apply the policy Daily sends back

Support replies with a suggested policy for your tenancy. It looks like this:
The OCIDs above are placeholders — support sends you the real ones, which are specific to your domain. Replace CUSTOMER-COMPARTMENT, BUCKET-NAME, and BUCKET-REGION with your own values.This policy is a suggestion, not a required form. It is written to be tightly scoped: access is limited to a single bucket, in a single region, for a single Daily principal. Depending on how your tenancy is organized you may prefer to express the same grant differently — a different compartment structure, or broader or narrower conditions. What matters is that the Daily group named by support ends up with the listed permissions on your bucket.

Step 4: Wait for the policy to propagate

OCI IAM changes are made in your tenancy’s home region and replicated outward. Oracle notes that this can take several minutes to reach all regions. If your bucket is not in your home region, allow 5–10 minutes before testing — a policy that has not finished propagating fails exactly like a policy that is wrong.

Step 5: Configure the property and test it

Set the bucket property on your domain or room, then verify it with the test-oci-bucket endpoint.

Configuring your Daily domain or room

OCI storage can be configured at the room or domain level, and applies to both recordings (recordings_bucket) and transcripts (transcription_bucket). Which configuration gets used depends on the following priority order (highest to lowest):
  1. Customer bucket at the room level
  2. Customer bucket at the domain level
  3. Daily’s default storage (no configuration needed)
bucket_region must be an OCI region such as us-ashburn-1, not an AWS region. The value is used to build the OCI storage endpoint hostname, so an AWS-style region like us-east-1 produces a connection failure rather than a permissions error.
Set a custom OCI bucket for recordings at the domain level:
Set a custom OCI bucket for transcripts at the domain level:
Set a custom OCI bucket at the room level:
Revert to Daily default storage:

Properties

assume_role_arn is an S3-only property and is rejected for OCI buckets. Likewise namespace is rejected for S3 buckets. Sending the wrong provider’s fields returns a 400.

What each permission is for

The policy Daily sends you grants a set of object-family permissions. The main ones map to Daily’s work like this: BUCKET_READ and OBJECT_DELETE are granted alongside these. They cover bucket-level metadata lookups and cleaning up uploads that could not be completed.

Optional: restricting read access

If your security policy says Daily should never read your recordings back, you can narrow the request.permission list in the Admit statement to the write-side permissions only. Ask support which permissions are safe to drop for your configuration — completing an interrupted multipart upload needs more than OBJECT_CREATE alone, so trimming the list by guesswork can leave recordings stranded. Here is what stops working once Daily cannot read the bucket:
  • Download and playback links from Daily. The recording access link API and the recording player in the Daily dashboard both sign a link with Daily’s credentials. Without read access that link fails when someone opens it. Set allow_api_access to false so your team is not handed links that cannot work.
  • The MP4 seek atom. Daily can add a seek atom (“faststart”) to finished MP4 files, which is what lets a player jump to the middle of a video without downloading all of it. That step reads the file back, so it cannot run.
  • Batch processor jobs. Anything that processes a finished recording has to read it first.
The recording files themselves are complete and valid either way. You can add the seek atom yourself after downloading:
Pair a read-restricted policy with allow_api_access: false. The bucket test generates a download link whenever allow_api_access is true, so a policy without read access combined with allow_api_access: true fails the test with upload succeeded but access-link generation failed — even though writes are working correctly.

Verifying your setup

Unlike S3 buckets, an OCI bucket configuration is not checked when you set it. Setting the property succeeds even if the policy is wrong or has not finished propagating, because Daily cannot usefully test the bucket at that moment. Use the test-oci-bucket endpoint to confirm the setup works before you rely on it.
Query parameters:
  • property — which property to test: recordings_bucket (default) or transcription_bucket.
  • roomName — test the room-level property on that room. Omit it to test the domain-level property. There is no fallback from room to domain; if the room does not set the property, the call returns a 400.
Example: test the transcription bucket
A successful response uploads daily-co-test-upload.txt to your bucket and returns:
The echoed configuration includes any defaults that were applied when the property was set — allow_streaming_from_bucket above was not sent by the caller. The download link is a standard AWS Signature Version 4 presigned URL against the OCI S3 compatibility endpoint; the credential and signature values are redacted here. download_link and expires are only returned when allow_api_access is true; the link is valid for one hour. Otherwise download_link explains that no link was generated.

Troubleshooting

If a test fails immediately after applying the policy, wait a few minutes and try again before changing anything — see step 4. If you have any questions or run into issues with the setup, contact us.