Search Documentation
Search across all documentation pages
Origins

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

AttributeTypeDescription
idstringUnique identifier with ori_ prefix (e.g., "ori_x9y8z7w6v5").
app_idstringID of the parent app that owns this origin (e.g., "app_k1l2m3n4o5"). Server-set.
namestringHuman-readable name.
descriptionstringOptional description.
providerstringStorage provider. One of "gcs", "s3", "r2", "http", or "transcodely" (system-managed, read-only).
permissionsstring[]Declared permissions: "read" and/or "write".
statusstringCurrent status. One of "active", "failed", "archived".
base_pathstringBase path prefix within the bucket (e.g., "videos/uploads/").
path_templatestringOutput path template with {variable} tokens (e.g., "{date}/{job_id}/{codec}_{resolution}"). Supported tokens — core: {job_id}, {video_id}, {timestamp}, {date}, {uuid}; output: {output_id}, {output_index}, {preset_id}, {codec}, {resolution}, {bitrate}, {format} (alias {type}), {framerate}, {quality}; segment (HLS/DASH): {segment_index}, {segment_number}, {segment_time}; thumbnail: {thumb_index}, {thumb_time}, {thumb_time_ms}. Must include at least one of {job_id}, {output_id}, {video_id}, or {uuid} so concurrent jobs sharing the origin can’t collide.
gcsobjectGCS configuration, present when provider is "gcs". Contains bucket. Credentials are never included.
s3objectS3 configuration, present when provider is "s3". Contains bucket, region, and optional endpoint. Credentials are never included.
httpobjectHTTP configuration, present when provider is "http". Contains base_url. Credentials are never included.
r2objectCloudflare R2 configuration, present when provider is "r2". Contains bucket, account_id or endpoint, and jurisdiction. Credentials are never included.
last_validated_atstringISO 8601 timestamp of last successful validation. Omitted if never validated.
validation_errorstringError from last failed validation. Omitted if status is not "failed".
created_atstringISO 8601 timestamp.
updated_atstringISO 8601 timestamp.
archived_atstringISO 8601 timestamp. Omitted if not archived.
is_managedbooleantrue for Transcodely-managed origins (auto-created during hosting provisioning). Managed origins cannot be modified or 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}",
  "gcs": { "bucket": "acme-video-assets" },
  "last_validated_at": "2025-01-15T10:30:00Z",
  "created_at": "2025-01-15T10:30:00Z",
  "updated_at": "2025-01-15T10:30:00Z"
}

Providers

ProviderReadWriteAuthentication
gcsYesYesService account JSON key.
s3YesYesAccess key ID and secret. AWS S3 or any S3-compatible service (Hetzner Object Storage, Wasabi, DigitalOcean Spaces, MinIO, Backblaze B2) via a custom endpoint.
r2YesYesR2 access key ID and secret. Account ID derives the endpoint, or supply a custom endpoint.
httpYesNoOptional custom headers.
transcodelySystem-managed. Auto-created for hosting-enabled apps and returned by Get/List; read-only — cannot be created, modified, or archived via the API.

The ValidationResult object

Returned when credentials are validated, either at creation, after credential rotation, or via the Validate endpoint.

AttributeTypeDescription
successbooleanWhether all declared permissions were validated.
can_readbooleanWhether read permission was validated.
can_writebooleanWhether write permission was validated.
read_errorstringError message if read validation failed.
write_errorstringError message if write validation failed.
validated_atstringISO 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/Create

Parameters

ParameterTypeRequiredDescription
namestringYesHuman-readable name (1-255 chars).
descriptionstringNoDescription (max 1000 chars).
permissionsstring[]YesDeclared permissions: "read" and/or "write". At least one required. HTTP origins only support "read".
base_pathstringNoBase path prefix within the bucket (max 1024 chars).
path_templatestringNoOutput path template (max 1024 chars). Supports the same {variable} tokens as the path_template attribute above.
gcsobjectOne ofGCS provider configuration. Exactly one of gcs, s3, or http must be provided.
gcs.bucketstringYesGCS bucket name (e.g., "my-video-bucket").
gcs.credentialsobjectYesGCS credentials.
gcs.credentials.service_account_jsonstringYesFull JSON content of the service account key file.
s3objectOne ofS3 provider configuration.
s3.bucketstringYesS3 bucket name.
s3.regionstringYesRegion (e.g., "us-east-1", or "fsn1" for Hetzner). Required even with a custom endpoint — the AWS SDK needs it for request signing.
s3.credentialsobjectYesS3 credentials.
s3.credentials.access_key_idstringYesAccess key ID.
s3.credentials.secret_access_keystringYesSecret access key.
s3.endpointstringNoOptional S3-compatible endpoint (e.g., "https://fsn1.your-objectstorage.com"). When set, Transcodely uses path-style addressing against this host instead of AWS. Omit for AWS S3. Must be a valid URI, max 256 chars.
r2objectOne ofCloudflare R2 provider configuration.
r2.bucketstringYesR2 bucket name (3-63 chars, must match ^[a-z0-9][a-z0-9.-]*[a-z0-9]$).
r2.account_idstringOne ofCloudflare account ID (must match ^[a-f0-9]{32}$). Exactly one of account_id or endpoint must be set.
r2.jurisdictionstringNoData residency. One of "default", "eu", "fedramp". Only valid when account_id is set; ignored when endpoint is supplied.
r2.endpointstringOne ofExplicit endpoint URL for custom domains or jurisdictions not enumerated above. Must be a valid URI, max 256 chars. Mutually exclusive with account_id.
r2.credentialsobjectYesR2 credentials (S3-compatible).
r2.credentials.access_key_idstringYesR2 access key ID.
r2.credentials.secret_access_keystringYesR2 secret access key.
httpobjectOne ofHTTP provider configuration (read-only).
http.base_urlstringYesBase URL (e.g., "https://cdn.example.com/videos/").
http.credentialsobjectNoOptional authentication headers.
http.credentials.headersobjectNoKey-value map of custom headers (max 20 pairs).
app_idstringNoTarget app (app_...). Portal/JWT callers pass it to create the origin in a specific app in their org (omit to use the org’s first active app); API-key callers may omit it (the key’s app is used) or pass their own app — a different app is rejected.

Returns

The Origin object and a ValidationResult confirming the credential check.

The origin and validation fields are both returned only on the raw Connect/JSON (curl) response. The JS, Python, and Go SDK create() methods return just the Origin — inspect its status/validation_error, or call Validate separately for the full can_read/can_write breakdown.

Example: GCS origin

Creates a read/write GCS origin from a bucket name and an inline service account JSON key, with base_path and path_template shaping where outputs land.

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}",
    "gcs": { "bucket": "acme-video-assets" },
    "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

A write-only AWS S3 origin authenticated with an access key ID and secret. region is required even when no custom endpoint is set, since the AWS SDK needs it for request signing.

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 (e.g. https://media.example.com) in place of account_id — see r2.endpoint above. Exactly one of the two must be set.


Retrieve an origin

Retrieve an origin by ID. Credentials are never included in responses.

POST /transcodely.v1.OriginService/Get

Parameters

ParameterTypeRequiredDescription
idstringYesOrigin 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}",
    "gcs": { "bucket": "acme-video-assets" },
    "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/List

Parameters

ParameterTypeRequiredDescription
providerstringNoFilter by provider: "gcs", "s3", "r2", "http", or "transcodely".
statusstringNoFilter by status: "active", "failed", or "archived".
permissionstringNoFilter by permission: "read" or "write".
include_archivedbooleanNoInclude archived origins. Default: false.
paginationobjectNoPagination parameters. See Pagination.
app_idstringNoFilter to a single app (app_...). Portal/JWT callers pass it to scope the list to one app (omit to return origins across all apps in the org); API-key callers may omit it (the key’s app is used) or pass their own app.

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
  }
}

Python SDK: client.origins.list() currently accepts only limit (pagination) and does not support the provider, status, permission, include_archived, or app_id filters. Filter client-side, or use the Go/JS SDKs or the raw API for server-side filtering.


Update an origin

Update an origin’s metadata and optionally rotate credentials. If credentials are provided, validation runs automatically. Transcodely-managed origins (is_managed: true) cannot be updated.

POST /transcodely.v1.OriginService/Update

Parameters

ParameterTypeRequiredDescription
idstringYesOrigin ID.
namestringNoNew name (1-255 chars).
descriptionstringNoNew description (max 1000 chars).
base_pathstringNoNew base path (max 1024 chars).
path_templatestringNoNew path template (max 1024 chars).
gcs_credentialsobjectNoUpdated GCS credentials. Triggers validation.
s3_credentialsobjectNoUpdated S3 credentials. Triggers validation.
r2_credentialsobjectNoUpdated R2 credentials (same shape as S3). Triggers validation.
http_credentialsobjectNoUpdated HTTP credentials. Triggers validation.

Returns

The updated Origin object. The raw Connect/JSON (curl) response also includes a ValidationResult when credentials were rotated. The JS, Python, and Go SDK update() methods return only the Origin — call Validate separately for the can_read/can_write breakdown.

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}",
    "gcs": { "bucket": "acme-video-assets" },
    "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/Validate

Parameters

ParameterTypeRequiredDescription
idstringYesOrigin 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. Transcodely-managed origins (is_managed: true) cannot be archived.

POST /transcodely.v1.OriginService/Archive

Parameters

ParameterTypeRequiredDescription
idstringYesOrigin 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"
  }
}