Search Documentation
Search across all documentation pages
Origins

Origins

Origins are storage locations where your source videos live and where transcoded outputs are written. Transcodely supports four storage providers: Google Cloud Storage (GCS), Amazon S3, Cloudflare R2, and HTTP/HTTPS endpoints.

Overview

Every transcoding job needs at least one origin — an input origin to read the source video, and an output origin to write the transcoded files. Origins store the credentials and configuration needed to access your storage buckets.

Job Request
  ├── Input Origin (read) — where the source video is
  └── Output Origin (write) — where outputs are written

Providers

ProviderProtocolPermissionsUse Case
GCSgs://Read + WriteGoogle Cloud users
S3s3://Read + WriteAWS or S3-compatible storage
R2s3://Read + WriteCloudflare R2 — zero egress fees
HTTPhttps://Read onlyCDNs, public URLs, third-party APIs

Creating a GCS Origin

curl -X POST https://api.transcodely.com/transcodely.v1.OriginService/Create 
  -H "Authorization: Bearer {{API_KEY}}" 
  -H "X-Organization-ID: org_a1b2c3d4e5" 
  -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": "{...service account key 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: "{...service account key JSON...}",
    },
  },
});
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": "{...service account key 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: "{...service account key JSON...}",
		},
	},
})

Credentials are validated at creation time. If validation fails, the origin is created with a failed status and the validation error is returned.

Creating an S3 Origin

curl -X POST https://api.transcodely.com/transcodely.v1.OriginService/Create 
  -H "Authorization: Bearer {{API_KEY}}" 
  -H "X-Organization-ID: org_a1b2c3d4e5" 
  -H "Content-Type: application/json" 
  -d '{
    "name": "AWS S3 Output",
    "permissions": ["read", "write"],
    "s3": {
      "bucket": "acme-transcoded-outputs",
      "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",
  permissions: [OriginPermission.READ, OriginPermission.WRITE],
  s3: {
    bucket: "acme-transcoded-outputs",
    region: "us-east-1",
    credentials: {
      accessKeyId: "AKIAIOSFODNN7EXAMPLE",
      secretAccessKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
    },
  },
});
origin = client.origins.create(
    name="AWS S3 Output",
    permissions=["read", "write"],
    s3={
        "bucket": "acme-transcoded-outputs",
        "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",
	Permissions: []transcodely.OriginPermission{transcodely.OriginPermissionRead, transcodely.OriginPermissionWrite},
	S3: &transcodely.S3OriginConfig{
		Bucket: "acme-transcoded-outputs",
		Region: "us-east-1",
		Credentials: &transcodely.S3Credentials{
			AccessKeyId:     "AKIAIOSFODNN7EXAMPLE",
			SecretAccessKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
		},
	},
})

Creating a Cloudflare R2 Origin

R2 supports two configuration styles. The recommended path supplies your Cloudflare account_id and lets us derive the endpoint server-side. An optional jurisdiction controls data residency.

curl -X POST https://api.transcodely.com/transcodely.v1.OriginService/Create 
  -H "Authorization: Bearer {{API_KEY}}" 
  -H "X-Organization-ID: org_a1b2c3d4e5" 
  -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",
    credentials: {
      accessKeyId: "...",
      secretAccessKey: "...",
    },
  },
});
origin = client.origins.create(
    name="Cloudflare R2 Outputs",
    permissions=["read", "write"],
    r2={
        "bucket": "acme-transcoded-outputs",
        "account_id": "f037e1abcd0987654321fedcba012345",
        "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",
		Credentials: &transcodely.S3Credentials{
			AccessKeyId:     "...",
			SecretAccessKey: "...",
		},
	},
})

Set jurisdiction to "eu" or "fedramp" for data residency. Omit it (or set "default") for the global jurisdiction.

For custom domains or jurisdictions not yet enumerated, supply an explicit endpoint URL instead of account_id. Exactly one of account_id or endpoint must be set; jurisdiction is ignored when endpoint is supplied.

"r2": {
  "bucket": "acme-transcoded-outputs",
  "endpoint": "https://media.example.com",
  "credentials": { "access_key_id": "...", "secret_access_key": "..." }
}

Creating an HTTP Origin

HTTP origins are read-only and are typically used for fetching source videos from CDNs or public URLs:

curl -X POST https://api.transcodely.com/transcodely.v1.OriginService/Create 
  -H "Authorization: Bearer {{API_KEY}}" 
  -H "X-Organization-ID: org_a1b2c3d4e5" 
  -H "Content-Type: application/json" 
  -d '{
    "name": "CDN Source",
    "permissions": ["read"],
    "http": {
      "base_url": "https://cdn.example.com/videos/",
      "credentials": {
        "headers": {
          "Authorization": "Bearer cdn_token_abc123"
        }
      }
    }
  }'
const origin = await client.origins.create({
  name: "CDN Source",
  permissions: [OriginPermission.READ],
  http: {
    baseUrl: "https://cdn.example.com/videos/",
    credentials: {
      headers: {
        Authorization: "Bearer cdn_token_abc123",
      },
    },
  },
});
origin = client.origins.create(
    name="CDN Source",
    permissions=["read"],
    http={
        "base_url": "https://cdn.example.com/videos/",
        "credentials": {
            "headers": {
                "Authorization": "Bearer cdn_token_abc123",
            },
        },
    },
)
origin, err := client.Origins.Create(ctx, &transcodely.OriginCreateParams{
	Name:        "CDN Source",
	Permissions: []transcodely.OriginPermission{transcodely.OriginPermissionRead},
	Http: &transcodely.HttpOriginConfig{
		BaseUrl: "https://cdn.example.com/videos/",
		Credentials: &transcodely.HttpCredentials{
			Headers: map[string]string{
				"Authorization": "Bearer cdn_token_abc123",
			},
		},
	},
})

Origin Status

StatusDescription
activeCredentials validated, origin is ready to use
failedCredential validation failed — check validation_error for details
archivedSoft-deleted, cannot be used for new jobs

Permissions

When creating an origin, you declare what permissions the credentials should have:

PermissionDescriptionRequired For
readList and download objectsInput origins
writeUpload objectsOutput origins

An origin used for both input and output should have both read and write permissions. HTTP origins only support read.

Path Templates

Origins can define a path_template that controls where output files are written. Templates support variables that are resolved at job creation time:

VariableExample ValueDescription
{job_id}job_a1b2c3d4e5f6Job identifier
{output_id}out_xyz789Output identifier
{date}2026-01-15Date in YYYY-MM-DD format
{timestamp}2026-01-15T10-30-00ZISO timestamp (file-safe)
{codec}h264Video codec
{resolution}1080pResolution preset
{format}mp4Output container format
{quality}standardQuality tier

Example: a path template of {date}/{job_id}/{codec}_{resolution} produces paths like 2026-01-15/job_a1b2c3/h264_1080p.mp4.

The base_path is prepended to all resolved paths. If base_path is videos/ and the resolved template is 2026-01-15/job_a1b2c3/output.mp4, the final path becomes videos/2026-01-15/job_a1b2c3/output.mp4.

Validation

Credentials are automatically validated when an origin is created or when credentials are updated. You can also re-validate at any time to check for permission drift:

curl -X POST https://api.transcodely.com/transcodely.v1.OriginService/Validate 
  -H "Authorization: Bearer {{API_KEY}}" 
  -H "X-Organization-ID: org_a1b2c3d4e5" 
  -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", "status": "active", "..." : "..." },
  "validation": {
    "success": true,
    "can_read": true,
    "can_write": true,
    "validated_at": "2026-01-15T10:30:00Z"
  }
}

Credential Security

Credentials are encrypted at rest and never returned in API responses. After creation, you can only see that credentials exist — not their values. To update credentials, provide new ones through the Update endpoint.

Archiving Origins

Archived origins cannot be used for new jobs, but existing job data stored in the origin remains accessible:

curl -X POST https://api.transcodely.com/transcodely.v1.OriginService/Archive 
  -H "Authorization: Bearer {{API_KEY}}" 
  -H "X-Organization-ID: org_a1b2c3d4e5" 
  -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")