---
title: "git.clone-request@1 · OpenVibe.Services"
canonical: "https://openvibe.services/docs/contracts/git.clone-request"
updated: null
---

# git.clone-request@1 · OpenVibe.Services

HTML: [git.clone-request@1 · OpenVibe.Services](https://openvibe.services/docs/contracts/git.clone-request)

# GitCloneRequest `git.clone-request@1`

Generated at 2026-11-13 06:25:48 UTC from [`openvibe-contracts v0.419.0`](https://github.com/OpenVibers/OpenVibe.Contracts/tree/v0.419.0) and [`openvibe-sdk v0.161.0`](https://github.com/OpenVibers/OpenVibe.SDK/tree/v0.161.0).

- Version: 1.0.0
- Owner: git
- Visibility: public
- Status: active
- Compatibility: backward
- Schema: [`https://openvibe.network/contracts/git/clone-request.v1.json`](/docs/contracts/git.clone-request.json)

One 'Clone to my computer' request from a repository page on OpenVibe.Git. Git mints it for the signed-in person and keeps it for two minutes. The person's Link reads it over an outbound HTTPS relay with the one-time token in the link, asks the person there, clones owner/name into a folder inside the root the person chose in Link, and reports progress back. The page polls the same document. clone\_url is present only in the answer to the Link (it carries a short-lived read token) and never in the page's copy.

## Fields

| Field | Type | Required | Description | Constraints |
| --- | --- | --- | --- | --- |
| `id` | string | yes | The request's own id (clr\_<ULID>), also the Link's idempotency key. | - `pattern ^clr_[0-9A-HJKMNP-TV-Z]{26}$` |
| `repo` | string | yes | owner/name, lower-case, exactly as the repository page names it. | - `pattern ^[a-z0-9][a-z0-9._-]*/[a-z0-9][a-z0-9._-]*$`<br>- `maxLength 220` |
| `state` | enum | yes | pending until the person answers in Link; approved when they say yes; cloning while git runs; done, refused, failed or expired after that. A request past expires\_at is expired, whatever the stored state. | - `one of "pending", "approved", "cloning", "done", "refused", "failed", "expired"` |
| `clone_url` | string |  | The HTTPS clone URL with a read-only, short-lived Git token, sent to the Link only. Never returned to the page. | - `format uri` |
| `created_at` | string | yes |  | - `format date-time` |
| `expires_at` | string | yes | created\_at + two minutes. Link refuses to start a clone after this. | - `format date-time` |
| `progress` | object |  |  | - `no other fields` |
| `progress.percent` | integer | yes |  | - `minimum 0`<br>- `maximum 100` |
| `progress.line` | string | yes | One line of git's own progress, with any token removed. | - `maxLength 200` |
| `path` | string |  | Where Link put the clone, only when state is done. | - `maxLength 4096` |
| `reason` | string |  | Why it was refused or failed, in words the page can show. | - `maxLength 300` |

## Examples

From the contract's own test fixtures: valid ones validate, rejected ones must fail.

 Valid: cloning

~~~~
{
  "id": "clr_01JQZ8M4T7Y2N5K3B6V9C1X0DA",
  "repo": "openvibers/openvibe.codes",
  "state": "cloning",
  "clone_url": "https://x-access-token:git_0123456789@git.openvibe.codes/openvibers/openvibe.codes.git",
  "created_at": "2026-11-10T09:00:00Z",
  "expires_at": "2026-11-10T09:02:00Z",
  "progress": {
    "percent": 42,
    "line": "Receiving objects:  42%"
  }
}
~~~~

Valid: done

~~~~
{
  "id": "clr_01JQZ8M4T7Y2N5K3B6V9C1X0DA",
  "repo": "openvibers/openvibe.codes",
  "state": "done",
  "created_at": "2026-11-10T09:00:00Z",
  "expires_at": "2026-11-10T09:02:00Z",
  "progress": {
    "percent": 100,
    "line": "Cloned into openvibe.codes"
  },
  "path": "/home/ada/OpenVibe/openvibe.codes"
}
~~~~

Valid: pending

~~~~
{
  "id": "clr_01JQZ8M4T7Y2N5K3B6V9C1X0DA",
  "repo": "openvibers/openvibe.codes",
  "state": "pending",
  "created_at": "2026-11-10T09:00:00Z",
  "expires_at": "2026-11-10T09:02:00Z"
}
~~~~

Rejected: bad-id

~~~~
{
  "id": "clone_01",
  "repo": "openvibers/openvibe.codes",
  "state": "pending",
  "created_at": "2026-11-10T09:00:00Z",
  "expires_at": "2026-11-10T09:02:00Z"
}
~~~~

Rejected: bad-state

~~~~
{
  "id": "clr_01JQZ8M4T7Y2N5K3B6V9C1X0DA",
  "repo": "openvibers/openvibe.codes",
  "state": "started",
  "created_at": "2026-11-10T09:00:00Z",
  "expires_at": "2026-11-10T09:02:00Z"
}
~~~~

Rejected: traversal-repo

~~~~
{
  "id": "clr_01JQZ8M4T7Y2N5K3B6V9C1X0DA",
  "repo": "../openvibers/openvibe.codes",
  "state": "pending",
  "created_at": "2026-11-10T09:00:00Z",
  "expires_at": "2026-11-10T09:02:00Z"
}
~~~~

## Validate

~~~~
const contracts = require('openvibe-contracts');
contracts.validate('git.clone-request@1', value);   // { valid, errors: [{ path, message }] }
~~~~
