Assign (or replace) the tenant's repository.
const url = 'https://shiftagent.example.com/tenants/example/repository';const options = { method: 'PUT', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"repository_id":"rep_01hzx8fieldops"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request PUT \ --url https://shiftagent.example.com/tenants/example/repository \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "repository_id": "rep_01hzx8fieldops" }'Idempotent assignment of the tenant’s single repository: 201 on
first assignment, 200 when an assignment already existed (fields
merged — provided → replaced, omitted → unchanged, null → cleared;
pointing at a different repository_id replaces the assignment).
This is cold-path step 2: assign the registry repository right after
the tenant upsert returns 201. A tenant has at most one
repository; roles narrow which of its skills are usable
(skill_access), and conversations/messages inherit it — there are
no per-role, per-user, per-conversation, or per-message repository
overrides.
branch_override reads a different branch of the same repository for
this tenant only.
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters ”Internal tenant ID.
Request Body required
Section titled “Request Body required ”Body for assignTenantRepository. Merge semantics: provided → replaced, omitted → unchanged, null → cleared.
object
The registry repository to assign. Pointing at a different repository replaces the assignment.
Read this branch for the tenant; null clears.
Examples
Cold-path assignment
{ "repository_id": "rep_01hzx8fieldops"}Responses
Section titled “ Responses ”Assignment already existed — fields merged/replaced.
A tenant’s repository assignment (each tenant has at most one). Addressed by the singular path /tenants/{tenant_id}/repository — no separate ID. Embeds the repository for convenience. inherited: true marks an assignment resolved from the nearest ancestor tenant.
object
The tenant addressed (not the ancestor when inherited).
Branch read for this tenant instead of the registry branch.
True when the tenant has no assignment of its own and this is the nearest ancestor’s.
The assigned repository, embedded.
object
Unique across the registry.
Git remote URL.
Branch scanned for skills (tenant attachments may override).
Git hosting flavor (drives auth mechanics).
Vault credential used to access the repository. Secret material is never readable — pre-authenticated at registration.
Skill-discovery sync state of a repository.
object
pending — not yet scanned (or invalidated by an update); syncing — scan in flight; ready — skill catalog current; error — last scan failed (see error).
Completion time of the last successful scan.
Human-readable failure reason when state is error.
Number of skills currently cataloged.
Free-form string key–value map for host/adapter bookkeeping (e.g. a host-side reference ID). Max 50 keys; values max 500 chars. Replaced wholesale when provided in updates.
object
RFC 3339 / ISO 8601 timestamp, UTC.
RFC 3339 / ISO 8601 timestamp, UTC.
RFC 3339 / ISO 8601 timestamp, UTC.
RFC 3339 / ISO 8601 timestamp, UTC.
Example
{ "object": "tenant.repository", "repository": { "object": "repository", "branch": "main", "provider": "github", "sync": { "state": "pending" } }}Repository assigned to the tenant.
A tenant’s repository assignment (each tenant has at most one). Addressed by the singular path /tenants/{tenant_id}/repository — no separate ID. Embeds the repository for convenience. inherited: true marks an assignment resolved from the nearest ancestor tenant.
object
The tenant addressed (not the ancestor when inherited).
Branch read for this tenant instead of the registry branch.
True when the tenant has no assignment of its own and this is the nearest ancestor’s.
The assigned repository, embedded.
object
Unique across the registry.
Git remote URL.
Branch scanned for skills (tenant attachments may override).
Git hosting flavor (drives auth mechanics).
Vault credential used to access the repository. Secret material is never readable — pre-authenticated at registration.
Skill-discovery sync state of a repository.
object
pending — not yet scanned (or invalidated by an update); syncing — scan in flight; ready — skill catalog current; error — last scan failed (see error).
Completion time of the last successful scan.
Human-readable failure reason when state is error.
Number of skills currently cataloged.
Free-form string key–value map for host/adapter bookkeeping (e.g. a host-side reference ID). Max 50 keys; values max 500 chars. Replaced wholesale when provided in updates.
object
RFC 3339 / ISO 8601 timestamp, UTC.
RFC 3339 / ISO 8601 timestamp, UTC.
RFC 3339 / ISO 8601 timestamp, UTC.
RFC 3339 / ISO 8601 timestamp, UTC.
Examples
Assigned
{ "object": "tenant.repository", "tenant_id": "tnt_01hzx8acme001", "repository_id": "rep_01hzx8fieldops", "branch_override": null, "inherited": false, "repository": { "object": "repository", "id": "rep_01hzx8fieldops", "name": "field-ops", "repo_url": "https://git.example.com/agent-skills/field-ops.git", "branch": "main", "provider": "generic", "credential_id": "crd_01hzx8gitmain", "sync": { "state": "ready", "last_synced_at": "2026-07-02T09:33:00Z", "error": null }, "skill_count": 5, "metadata": {}, "created_at": "2026-07-02T09:31:00Z", "updated_at": "2026-07-02T09:33:00Z" }, "created_at": "2026-07-02T09:34:00Z", "updated_at": "2026-07-02T09:34:00Z"}Missing or invalid credentials — no bearer token, an unknown/revoked sk_int_ key, or an expired platform JWT.
RFC 9457 problem+json error envelope. type is a URI under https://shiftagent.example.com/problems/{slug} (deployment host substituted); see the API-level problem registry for every slug.
object
Problem type URI (registry slug).
Short, human-readable summary of the problem type.
HTTP status code.
Human-readable explanation specific to this occurrence.
URI reference identifying this occurrence.
Correlation ID for support and log lookup.
On name-conflict, external-id-conflict, and resource-in-use: the ID of the existing/depended-on resource — fetch it and continue (replay recovery).
On validation-error, field-level details.
object
JSON pointer to the offending field.
What failed.
Examples
Missing or invalid bearer token
{ "type": "https://shiftagent.example.com/problems/insufficient-scope", "title": "Unauthorized", "status": 401, "detail": "Provide a valid sk_int_ service key or platform JWT.", "request_id": "req_01hzx8auth001"}Not found — the resource does not exist, was deprovisioned, or lies outside the integration key’s subtree (indistinguishable by design).
RFC 9457 problem+json error envelope. type is a URI under https://shiftagent.example.com/problems/{slug} (deployment host substituted); see the API-level problem registry for every slug.
object
Problem type URI (registry slug).
Short, human-readable summary of the problem type.
HTTP status code.
Human-readable explanation specific to this occurrence.
URI reference identifying this occurrence.
Correlation ID for support and log lookup.
On name-conflict, external-id-conflict, and resource-in-use: the ID of the existing/depended-on resource — fetch it and continue (replay recovery).
On validation-error, field-level details.
object
JSON pointer to the offending field.
What failed.
Examples
Unknown resource
{ "type": "https://shiftagent.example.com/problems/not-found", "title": "Not found", "status": 404, "detail": "No tenant with external_id acme:tenant:999999.", "request_id": "req_01hzx8nf001"}Unprocessable — validation-error (schema/semantic validation failed; errors[] lists JSON-pointer details), role-required (the user has no role assigned, so no conversation context can resolve), or missing-secret (a referenced alias is vaulted at no scope).
RFC 9457 problem+json error envelope. type is a URI under https://shiftagent.example.com/problems/{slug} (deployment host substituted); see the API-level problem registry for every slug.
object
Problem type URI (registry slug).
Short, human-readable summary of the problem type.
HTTP status code.
Human-readable explanation specific to this occurrence.
URI reference identifying this occurrence.
Correlation ID for support and log lookup.
On name-conflict, external-id-conflict, and resource-in-use: the ID of the existing/depended-on resource — fetch it and continue (replay recovery).
On validation-error, field-level details.
object
JSON pointer to the offending field.
What failed.
Examples
Field-level validation failure
{ "type": "https://shiftagent.example.com/problems/validation-error", "title": "Validation error", "status": 422, "detail": "One or more fields failed validation.", "errors": [ { "pointer": "/skill_access/skill_ids/0", "message": "skl_01hzx8unknown does not belong to the tenant's repository." } ], "request_id": "req_01hzx8val001"}User has no role at conversation creation
{ "type": "https://shiftagent.example.com/problems/role-required", "title": "Role required", "status": 422, "detail": "User usr_01hzx8jane001 has no role assigned; assign one before starting conversations.", "request_id": "req_01hzx8role01"}