The Origin object
Origins are storage locations for video inputs and transcoded outputs. Transcodely supports Google Cloud Storage, Amazon S3, Cloudflare R2, and HTTP/HTTPS endpoints. Credentials are validated at creation and stored encrypted.
Base path: transcodely.v1.OriginService Requires: X-Organization-ID header on all endpoints.
Attributes
| Attribute | Type | Description |
|---|---|---|
id | string | Unique identifier with ori_ prefix (e.g., "ori_x9y8z7w6v5"). |
name | string | Human-readable name. |
description | string | Optional description. |
provider | string | Storage provider. One of "gcs", "s3", "r2", "http". |
permissions | string[] | Declared permissions: "read" and/or "write". |
status | string | Current status. One of "active", "failed", "archived". |
base_path | string | Base path prefix within the bucket (e.g., "videos/uploads/"). |
path_template | string | Output path template with variables (e.g., "{date}/{job_id}/{codec}_{resolution}"). Supports {date}, {job_id}, {output_id}, {codec}, {resolution}. |
last_validated_at | string | ISO 8601 timestamp of last successful validation. Omitted if never validated. |
validation_error | string | Error from last failed validation. Omitted if status is not "failed". |
created_at | string | ISO 8601 timestamp. |
updated_at | string | ISO 8601 timestamp. |
archived_at | string | ISO 8601 timestamp. Omitted if not archived. |
{
"id": "ori_x9y8z7w6v5",
"name": "Production GCS Bucket",
"description": "Main storage for video assets",
"provider": "gcs",
"permissions": ["read", "write"],
"status": "active",
"base_path": "videos/",
"path_template": "{date}/{job_id}/{codec}_{resolution}",
"last_validated_at": "2025-01-15T10:30:00Z",
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:30:00Z"
}Providers
| Provider | Read | Write | Authentication |
|---|---|---|---|
gcs | Yes | Yes | Service account JSON key. |
s3 | Yes | Yes | Access key ID and secret. |
r2 | Yes | Yes | R2 access key ID and secret. Account ID derives the endpoint, or supply a custom endpoint. |
http | Yes | No | Optional custom headers. |
The ValidationResult object
Returned when credentials are validated, either at creation, after credential rotation, or via the Validate endpoint.
| Attribute | Type | Description |
|---|---|---|
success | boolean | Whether all declared permissions were validated. |
can_read | boolean | Whether read permission was validated. |
can_write | boolean | Whether write permission was validated. |
read_error | string | Error message if read validation failed. |
write_error | string | Error message if write validation failed. |
validated_at | string | ISO 8601 timestamp. |
Create an origin
Create a new storage origin. Credentials are validated at creation time and must pass before the origin is stored.
POST /transcodely.v1.OriginService/CreateParameters
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Human-readable name (1-255 chars). |
description | string | No | Description (max 1000 chars). |
permissions | string[] | Yes | Declared permissions: "read" and/or "write". At least one required. HTTP origins only support "read". |
base_path | string | No | Base path prefix within the bucket (max 1024 chars). |
path_template | string | No | Output path template with variables like {date}, {job_id}, {output_id}, {codec}, {resolution} (max 1024 chars). |
gcs | object | One of | GCS provider configuration. Exactly one of gcs, s3, or http must be provided. |
gcs.bucket | string | Yes | GCS bucket name (e.g., "my-video-bucket"). |
gcs.credentials | object | Yes | GCS credentials. |
gcs.credentials.service_account_json | string | Yes | Full JSON content of the service account key file. |
s3 | object | One of | S3 provider configuration. |
s3.bucket | string | Yes | S3 bucket name. |
s3.region | string | Yes | AWS region (e.g., "us-east-1"). |
s3.credentials | object | Yes | S3 credentials. |
s3.credentials.access_key_id | string | Yes | AWS access key ID. |
s3.credentials.secret_access_key | string | Yes | AWS secret access key. |
r2 | object | One of | Cloudflare R2 provider configuration. |
r2.bucket | string | Yes | R2 bucket name (3-63 chars, must match ^[a-z0-9][a-z0-9.-]*[a-z0-9]$). |
r2.account_id | string | One of | Cloudflare account ID (must match ^[a-f0-9]{32}$). Exactly one of account_id or endpoint must be set. |
r2.jurisdiction | string | No | Data residency. One of "default", "eu", "fedramp". Only valid when account_id is set; ignored when endpoint is supplied. |
r2.endpoint | string | One of | Explicit endpoint URL for custom domains or jurisdictions not enumerated above. Must be a valid URI, max 256 chars. Mutually exclusive with account_id. |
r2.credentials | object | Yes | R2 credentials (S3-compatible). |
r2.credentials.access_key_id | string | Yes | R2 access key ID. |
r2.credentials.secret_access_key | string | Yes | R2 secret access key. |
http | object | One of | HTTP provider configuration (read-only). |
http.base_url | string | Yes | Base URL (e.g., "https://cdn.example.com/videos/"). |
http.credentials | object | No | Optional authentication headers. |
http.credentials.headers | object | No | Key-value map of custom headers (max 20 pairs). |
Returns
The Origin object and a ValidationResult confirming the credential check.
Example: GCS origin
curl -X POST https://api.transcodely.com/transcodely.v1.OriginService/Create
-H "Authorization: Bearer {{API_KEY}}"
-H "X-Organization-ID: {{ORG_ID}}"
-H "Content-Type: application/json"
-d '{
"name": "Production GCS Bucket",
"description": "Main storage for video assets",
"permissions": ["read", "write"],
"base_path": "videos/",
"path_template": "{date}/{job_id}/{codec}_{resolution}",
"gcs": {
"bucket": "acme-video-assets",
"credentials": {
"service_account_json": "{...}"
}
}
}'const origin = await client.origins.create({
name: "Production GCS Bucket",
description: "Main storage for video assets",
permissions: [OriginPermission.READ, OriginPermission.WRITE],
basePath: "videos/",
pathTemplate: "{date}/{job_id}/{codec}_{resolution}",
gcs: {
bucket: "acme-video-assets",
credentials: {
serviceAccountJson: "{...}",
},
},
});origin = client.origins.create(
name="Production GCS Bucket",
description="Main storage for video assets",
permissions=["read", "write"],
base_path="videos/",
path_template="{date}/{job_id}/{codec}_{resolution}",
gcs={
"bucket": "acme-video-assets",
"credentials": {
"service_account_json": "{...}",
},
},
)origin, err := client.Origins.Create(ctx, &transcodely.OriginCreateParams{
Name: "Production GCS Bucket",
Description: "Main storage for video assets",
Permissions: []transcodely.OriginPermission{transcodely.OriginPermissionRead, transcodely.OriginPermissionWrite},
BasePath: "videos/",
PathTemplate: "{date}/{job_id}/{codec}_{resolution}",
Gcs: &transcodely.GcsOriginConfig{
Bucket: "acme-video-assets",
Credentials: &transcodely.GcsCredentials{
ServiceAccountJson: "{...}",
},
},
}){
"origin": {
"id": "ori_x9y8z7w6v5",
"name": "Production GCS Bucket",
"description": "Main storage for video assets",
"provider": "gcs",
"permissions": ["read", "write"],
"status": "active",
"base_path": "videos/",
"path_template": "{date}/{job_id}/{codec}_{resolution}",
"last_validated_at": "2025-01-15T10:30:00Z",
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:30:00Z"
},
"validation": {
"success": true,
"can_read": true,
"can_write": true,
"read_error": "",
"write_error": "",
"validated_at": "2025-01-15T10:30:00Z"
}
}Example: S3 origin
curl -X POST https://api.transcodely.com/transcodely.v1.OriginService/Create
-H "Authorization: Bearer {{API_KEY}}"
-H "X-Organization-ID: {{ORG_ID}}"
-H "Content-Type: application/json"
-d '{
"name": "AWS S3 Output Bucket",
"permissions": ["write"],
"s3": {
"bucket": "acme-transcoded-output",
"region": "us-east-1",
"credentials": {
"access_key_id": "AKIAIOSFODNN7EXAMPLE",
"secret_access_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}
}
}'const origin = await client.origins.create({
name: "AWS S3 Output Bucket",
permissions: [OriginPermission.WRITE],
s3: {
bucket: "acme-transcoded-output",
region: "us-east-1",
credentials: {
accessKeyId: "AKIAIOSFODNN7EXAMPLE",
secretAccessKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
},
},
});origin = client.origins.create(
name="AWS S3 Output Bucket",
permissions=["write"],
s3={
"bucket": "acme-transcoded-output",
"region": "us-east-1",
"credentials": {
"access_key_id": "AKIAIOSFODNN7EXAMPLE",
"secret_access_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
},
},
)origin, err := client.Origins.Create(ctx, &transcodely.OriginCreateParams{
Name: "AWS S3 Output Bucket",
Permissions: []transcodely.OriginPermission{transcodely.OriginPermissionWrite},
S3: &transcodely.S3OriginConfig{
Bucket: "acme-transcoded-output",
Region: "us-east-1",
Credentials: &transcodely.S3Credentials{
AccessKeyId: "AKIAIOSFODNN7EXAMPLE",
SecretAccessKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
},
},
})Example: Cloudflare R2 origin
The recommended form supplies an account_id and lets us derive the endpoint.
curl -X POST https://api.transcodely.com/transcodely.v1.OriginService/Create
-H "Authorization: Bearer {{API_KEY}}"
-H "X-Organization-ID: {{ORG_ID}}"
-H "Content-Type: application/json"
-d '{
"name": "Cloudflare R2 Outputs",
"permissions": ["read", "write"],
"r2": {
"bucket": "acme-transcoded-outputs",
"account_id": "f037e1abcd0987654321fedcba012345",
"credentials": {
"access_key_id": "...",
"secret_access_key": "..."
}
}
}'const origin = await client.origins.create({
name: "Cloudflare R2 Outputs",
permissions: [OriginPermission.READ, OriginPermission.WRITE],
r2: {
bucket: "acme-transcoded-outputs",
accountId: "f037e1abcd0987654321fedcba012345",
jurisdiction: R2Jurisdiction.DEFAULT, // or EU, FEDRAMP
credentials: {
accessKeyId: "...",
secretAccessKey: "...",
},
},
});origin = client.origins.create(
name="Cloudflare R2 Outputs",
permissions=["read", "write"],
r2={
"bucket": "acme-transcoded-outputs",
"account_id": "f037e1abcd0987654321fedcba012345",
"jurisdiction": "default", # or "eu", "fedramp"
"credentials": {
"access_key_id": "...",
"secret_access_key": "...",
},
},
)origin, err := client.Origins.Create(ctx, &transcodely.OriginCreateParams{
Name: "Cloudflare R2 Outputs",
Permissions: []transcodely.OriginPermission{transcodely.OriginPermissionRead, transcodely.OriginPermissionWrite},
R2: &transcodely.R2OriginConfig{
Bucket: "acme-transcoded-outputs",
AccountId: "f037e1abcd0987654321fedcba012345",
Jurisdiction: transcodely.R2JurisdictionDefault, // or EU, FedRAMP
Credentials: &transcodely.S3Credentials{
AccessKeyId: "...",
SecretAccessKey: "...",
},
},
})For custom domains or non-standard regions, supply an explicit endpoint instead.
"r2": {
"bucket": "acme-transcoded-outputs",
"endpoint": "https://media.example.com",
"credentials": { "access_key_id": "...", "secret_access_key": "..." }
}Retrieve an origin
Retrieve an origin by ID. Credentials are never included in responses.
POST /transcodely.v1.OriginService/GetParameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Origin ID (e.g., "ori_x9y8z7w6v5"). |
Returns
The Origin object.
Example
curl -X POST https://api.transcodely.com/transcodely.v1.OriginService/Get
-H "Authorization: Bearer {{API_KEY}}"
-H "X-Organization-ID: {{ORG_ID}}"
-H "Content-Type: application/json"
-d '{"id": "ori_x9y8z7w6v5"}'const origin = await client.origins.get("ori_x9y8z7w6v5");origin = client.origins.get("ori_x9y8z7w6v5")origin, err := client.Origins.Get(ctx, "ori_x9y8z7w6v5"){
"origin": {
"id": "ori_x9y8z7w6v5",
"name": "Production GCS Bucket",
"description": "Main storage for video assets",
"provider": "gcs",
"permissions": ["read", "write"],
"status": "active",
"base_path": "videos/",
"path_template": "{date}/{job_id}/{codec}_{resolution}",
"last_validated_at": "2025-01-15T10:30:00Z",
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:30:00Z"
}
}List origins
List origins with optional filtering by provider, status, and permission.
POST /transcodely.v1.OriginService/ListParameters
| Parameter | Type | Required | Description |
|---|---|---|---|
provider | string | No | Filter by provider: "gcs", "s3", "r2", or "http". |
status | string | No | Filter by status: "active", "failed", or "archived". |
permission | string | No | Filter by permission: "read" or "write". |
include_archived | boolean | No | Include archived origins. Default: false. |
pagination | object | No | Pagination parameters. See Pagination. |
Returns
A list of Origin objects and pagination metadata.
Example
curl -X POST https://api.transcodely.com/transcodely.v1.OriginService/List
-H "Authorization: Bearer {{API_KEY}}"
-H "X-Organization-ID: {{ORG_ID}}"
-H "Content-Type: application/json"
-d '{
"provider": "gcs",
"permission": "write",
"pagination": {"limit": 20}
}'for await (const origin of client.origins.list({
provider: OriginProvider.GCS,
permission: OriginPermission.WRITE,
pagination: { limit: 20 },
}).autoPage()) {
console.log(origin.id, origin.provider);
}for origin in client.origins.list(limit=20).auto_paging_iter():
print(origin.id, origin.provider)iter := client.Origins.List(ctx, &transcodely.OriginListParams{
Provider: transcodely.OriginProviderGCS.Enum(),
Permission: transcodely.OriginPermissionWrite.Enum(),
Pagination: &transcodely.PaginationRequest{Limit: 20},
})
for iter.Next() {
origin := iter.Current()
fmt.Println(origin.GetId(), origin.GetProvider())
}
if err := iter.Err(); err != nil {
log.Fatal(err)
}{
"origins": [
{
"id": "ori_x9y8z7w6v5",
"name": "Production GCS Bucket",
"provider": "gcs",
"permissions": ["read", "write"],
"status": "active",
"base_path": "videos/",
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:30:00Z"
}
],
"pagination": {
"next_cursor": "",
"total_count": 1
}
}Update an origin
Update an origin’s metadata and optionally rotate credentials. If credentials are provided, validation runs automatically.
POST /transcodely.v1.OriginService/UpdateParameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Origin ID. |
name | string | No | New name (1-255 chars). |
description | string | No | New description (max 1000 chars). |
base_path | string | No | New base path (max 1024 chars). |
path_template | string | No | New path template (max 1024 chars). |
gcs_credentials | object | No | Updated GCS credentials. Triggers validation. |
s3_credentials | object | No | Updated S3 credentials. Triggers validation. |
r2_credentials | object | No | Updated R2 credentials (same shape as S3). Triggers validation. |
http_credentials | object | No | Updated HTTP credentials. Triggers validation. |
Returns
The updated Origin object. Includes a ValidationResult if credentials were rotated.
Example
curl -X POST https://api.transcodely.com/transcodely.v1.OriginService/Update
-H "Authorization: Bearer {{API_KEY}}"
-H "X-Organization-ID: {{ORG_ID}}"
-H "Content-Type: application/json"
-d '{
"id": "ori_x9y8z7w6v5",
"name": "Production GCS (Updated)",
"path_template": "{job_id}/{output_id}"
}'const origin = await client.origins.update({
id: "ori_x9y8z7w6v5",
name: "Production GCS (Updated)",
pathTemplate: "{job_id}/{output_id}",
});origin = client.origins.update(
id="ori_x9y8z7w6v5",
name="Production GCS (Updated)",
path_template="{job_id}/{output_id}",
)origin, err := client.Origins.Update(ctx, &transcodely.OriginUpdateParams{
Id: "ori_x9y8z7w6v5",
Name: proto.String("Production GCS (Updated)"),
PathTemplate: proto.String("{job_id}/{output_id}"),
}){
"origin": {
"id": "ori_x9y8z7w6v5",
"name": "Production GCS (Updated)",
"description": "Main storage for video assets",
"provider": "gcs",
"permissions": ["read", "write"],
"status": "active",
"base_path": "videos/",
"path_template": "{job_id}/{output_id}",
"last_validated_at": "2025-01-15T10:30:00Z",
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-02-28T15:00:00Z"
}
}Validate an origin
Re-validate an origin’s credentials and permissions. Use this to check for permission drift after IAM policy changes.
POST /transcodely.v1.OriginService/ValidateParameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Origin ID. |
Returns
The Origin object (status may change to "active" or "failed") and a ValidationResult.
Example
curl -X POST https://api.transcodely.com/transcodely.v1.OriginService/Validate
-H "Authorization: Bearer {{API_KEY}}"
-H "X-Organization-ID: {{ORG_ID}}"
-H "Content-Type: application/json"
-d '{"id": "ori_x9y8z7w6v5"}'const result = await client.origins.validate({ id: "ori_x9y8z7w6v5" });
console.log(result.validation?.success, result.validation?.canWrite);result = client.origins.validate(id="ori_x9y8z7w6v5")
print(result.validation.success, result.validation.can_write)validation, err := client.Origins.Validate(ctx, "ori_x9y8z7w6v5")
fmt.Println(validation.GetSuccess(), validation.GetCanWrite()){
"origin": {
"id": "ori_x9y8z7w6v5",
"name": "Production GCS Bucket",
"provider": "gcs",
"permissions": ["read", "write"],
"status": "active",
"last_validated_at": "2025-02-28T15:00:00Z",
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-02-28T15:00:00Z"
},
"validation": {
"success": true,
"can_read": true,
"can_write": true,
"read_error": "",
"write_error": "",
"validated_at": "2025-02-28T15:00:00Z"
}
}Archive an origin
Soft-delete an origin. Archived origins cannot be used for new jobs, but existing job data is preserved.
POST /transcodely.v1.OriginService/ArchiveParameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Origin ID. |
Returns
The archived Origin object with status: "archived".
Example
curl -X POST https://api.transcodely.com/transcodely.v1.OriginService/Archive
-H "Authorization: Bearer {{API_KEY}}"
-H "X-Organization-ID: {{ORG_ID}}"
-H "Content-Type: application/json"
-d '{"id": "ori_x9y8z7w6v5"}'const origin = await client.origins.archive("ori_x9y8z7w6v5");origin = client.origins.archive("ori_x9y8z7w6v5")err := client.Origins.Archive(ctx, "ori_x9y8z7w6v5"){
"origin": {
"id": "ori_x9y8z7w6v5",
"name": "Production GCS Bucket",
"provider": "gcs",
"permissions": ["read", "write"],
"status": "archived",
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-02-28T15:00:00Z",
"archived_at": "2025-02-28T15:00:00Z"
}
}