Your Code. Your Rules.

API Reference

Complete /api/v0 HTTP reference for git.eu: authentication, the response envelope, status semantics, every endpoint, and every problem type.

git.eu API Reference

Last updated: 2026-09-24

Overview

The git.eu HTTP API serves your repositories as JSON. Every instance exposes it on its own host, under /api/v0 - for example https://<INSTANCE>.git.eu/api/v0/repos.

  • v0 is a beta surface. It is not frozen: routes, fields and problem types may change without a compatibility shim.
  • Requests and responses are JSON only. Send Content-Type: application/json with every request that carries a body.
  • Every route requires a bearer token. There is no anonymous access - see Authentication below.

Authentication

Every request carries a personal access token in the Authorization header:

Authorization: Bearer giteu_your_token

The token must hold the api scope. Create one under Settings - Tokens on your instance (https://<INSTANCE>.git.eu/settings/tokens), tick the api scope, and copy the value: it is shown once and never again. The Git Access guide walks through token creation in detail.

A token holding only the git scope works for git clone, fetch and push, but not for this API.

The API deliberately diverges from the website: there is no anonymous access, ever. A missing, malformed, expired, revoked or api-less token is answered 401 on every route - including a read of a public repository, which the website serves to signed-out visitors.

Response Envelope

Every JSON body uses the same envelope: exactly one of data and error is set - never both, never neither.

MemberTypeRequiredDescription
datapayload or nullyesThe successful payload, or null on an error.
errorerror object or nullyesThe error object (see Errors), or null on success.
linksobjectnoOptional related URLs (self, next, prev).
metaobjectnoOptional non-payload metadata.

A successful response:

{
  "data": {
    "name": "my-repo",
    "isPrivate": false
  },
  "error": null
}

A failed response, served as application/problem+json:

{
  "data": null,
  "error": {
    "type": "not_found",
    "title": "Not found",
    "status": 404
  }
}

Status Semantics

RuleBehavior
Authentication comes firstThe bearer-token check runs before any access decision. An unauthenticated call is always 401, whatever the target repository is.
Hidden, never refusedA repository the token may not see is reported as not found, never as a distinguishable access error - the API never confirms that a private repository exists.
Batch always succeeds as a wholeA batch create replies 200 with a per-item result array. Each item carries its own outcome; the response status is never 207 and never reflects an item failure.
Delete replies 204A successful delete returns 204 with an empty body - the only route that returns no envelope.
Validation is rejected up frontRequest bodies, path parameters and query strings are schema-validated before any work happens; a violation is a validation_failed problem.

Endpoints

POST /api/v0/repos/batch

Creates one or more repositories owned by the calling token. This is the only create route: a single create is a one-item batch. Every item is attempted independently, so one failure never aborts the rest; the response is always 200 with a per-item result array (never 207).

PropertyValue
AccessCaller-scoped: the route only ever touches repositories owned by the token holder, so no per-repository access decision is made.
Success status200
Success bodyThe standard JSON envelope, payload in data.

Request body

FieldTypeRequiredDescription
reposarray of object (1-50 items)yesThe repositories to create, 1 to 50 per call. Each item is attempted independently: one failing item never aborts the others.
repos[].displayNamestring (1-128 chars)yesHuman-readable repository name. Required: it is never filled in from your account defaults.
repos[].slugstring (1-128 chars)noURL slug of the repository. Omit it and a slug is generated from the display name; a value you send is always used as is. Letters, digits, ., _, -; starts and ends with a letter or digit; no two of ._- in a row; may not end in .git, .atom or .html; 1-128 characters.
repos[].descriptionstring (max 1024 chars)noFree-text description. Omit it and the repository is created without one; a value you send is always used as is.
repos[].isPrivatebooleannoTrue to create a private repository. Omit it and your account default applies; a value you send always wins, including an explicit false.
repos[].defaultBranchstring (max 64 chars)noName of the default branch. Omit it and your account default applies; a value you send always wins.

Response payload

The envelope's data member is an array; each element carries:

FieldTypeRequiredDescription
indexnumberyesZero-based position of the item in the submitted repos array.
statusstring (one of created, failed)yesOutcome of this item: created on success, failed otherwise.
repoobjectnoA repository as returned by the API.
repo.ownerstringyesUsername of the repository owner (the bearer token's user).
repo.namestringyesURL slug of the repository - the :name segment of every repository route.
repo.displayNamestringyesHuman-readable repository name.
repo.descriptionstring or nullyesFree-text description, or null when the repository has none.
repo.isPrivatebooleanyesTrue when the repository is private (visible to authorized users only).
repo.defaultBranchstringyesName of the default branch.
repo.createdAtstringyesCreation timestamp, ISO 8601.
repo.updatedAtstringyesLast-modification timestamp, ISO 8601.
errorobjectnoWhy this item failed - absent when the item succeeded.

Example request

curl -X POST https://<INSTANCE>.git.eu/api/v0/repos/batch \
  -H "Authorization: Bearer giteu_your_token" \
  -H "Content-Type: application/json" \
  -d '{"repos":[{"displayName":"string"}]}'

Errors

TypeStatusTitle
unauthorized401Unauthorized
validation_failed400Validation Failed

Per-item errors

These never change the response status: they are carried by a failed item inside an otherwise successful 200 response.

TypeStatusTitle
slug_taken409Slug already taken
invalid_slug400Invalid repository name
invalid_branch400Invalid branch name
invalid_visibility400Invalid visibility
invalid_description400Invalid description
disk_init_failed500Repository initialization failed

GET /api/v0/repos

Lists every repository owned by the calling token's user, optionally sorted and filtered. There is no pagination: the full owned list is returned.

PropertyValue
AccessCaller-scoped: the route only ever touches repositories owned by the token holder, so no per-repository access decision is made.
Success status200
Success bodyThe standard JSON envelope, payload in data.

Query parameters

Optional sort/filter of the returned list. There is no pagination.

FieldTypeRequiredDescription
sortstringnoSort token: name-asc, name-desc, created-desc or created-asc. Omitted or unrecognized: the default order applies (the value is ignored, never rejected).
filterstringnoCase-insensitive free-text needle matched against the repository name. Omitted or empty: no filtering.

Response payload

The envelope's data member is an array; each element carries:

FieldTypeRequiredDescription
ownerstringyesUsername of the repository owner (the bearer token's user).
namestringyesURL slug of the repository - the :name segment of every repository route.
displayNamestringyesHuman-readable repository name.
descriptionstring or nullyesFree-text description, or null when the repository has none.
isPrivatebooleanyesTrue when the repository is private (visible to authorized users only).
defaultBranchstringyesName of the default branch.
createdAtstringyesCreation timestamp, ISO 8601.
updatedAtstringyesLast-modification timestamp, ISO 8601.

Example request

curl -X GET https://<INSTANCE>.git.eu/api/v0/repos \
  -H "Authorization: Bearer giteu_your_token"

Errors

TypeStatusTitle
unauthorized401Unauthorized
validation_failed400Validation Failed

GET /api/v0/repos/:owner/:name

Returns a single repository. A repository the caller may not read is reported as not found, never as a distinguishable access error.

PropertyValue
AccessRead access to the target repository.
Success status200
Success bodyThe standard JSON envelope, payload in data.

Path parameters

FieldTypeRequiredDescription
ownerstring (6-42 chars)yesUsername of the repository owner. Letters, digits, ., _, -; starts and ends with a letter or digit; no two of ._- in a row; may not end in .git, .atom or .html; 6-42 characters.
namestring (1-128 chars)yesURL slug of the repository. Letters, digits, ., _, -; starts and ends with a letter or digit; no two of ._- in a row; may not end in .git, .atom or .html; 1-128 characters.

Response payload

The envelope's data member carries:

FieldTypeRequiredDescription
ownerstringyesUsername of the repository owner (the bearer token's user).
namestringyesURL slug of the repository - the :name segment of every repository route.
displayNamestringyesHuman-readable repository name.
descriptionstring or nullyesFree-text description, or null when the repository has none.
isPrivatebooleanyesTrue when the repository is private (visible to authorized users only).
defaultBranchstringyesName of the default branch.
createdAtstringyesCreation timestamp, ISO 8601.
updatedAtstringyesLast-modification timestamp, ISO 8601.

Example request

curl -X GET https://<INSTANCE>.git.eu/api/v0/repos/<USERNAME>/{name} \
  -H "Authorization: Bearer giteu_your_token"

Errors

TypeStatusTitle
unauthorized401Unauthorized
not_found404Not Found
forbidden403Forbidden
validation_failed400Validation Failed

PATCH /api/v0/repos/:owner/:name

Updates a repository. Only the fields present in the body change; an absent field is left untouched, and no account default is ever merged in on update.

PropertyValue
AccessAdministrative access to the target repository.
Success status200
Success bodyThe standard JSON envelope, payload in data.

Path parameters

FieldTypeRequiredDescription
ownerstring (6-42 chars)yesUsername of the repository owner. Letters, digits, ., _, -; starts and ends with a letter or digit; no two of ._- in a row; may not end in .git, .atom or .html; 6-42 characters.
namestring (1-128 chars)yesURL slug of the repository. Letters, digits, ., _, -; starts and ends with a letter or digit; no two of ._- in a row; may not end in .git, .atom or .html; 1-128 characters.

Request body

The repository fields to change. Every field is optional; an absent field is left unchanged, and no account default is ever merged in on update.

FieldTypeRequiredDescription
displayNamestring (1-128 chars)noNew human-readable repository name. Absent: unchanged.
slugstring (1-128 chars)noNew URL slug. Absent: unchanged. Changing it changes every URL of the repository. Letters, digits, ., _, -; starts and ends with a letter or digit; no two of ._- in a row; may not end in .git, .atom or .html; 1-128 characters.
descriptionstring (max 1024 chars)noNew free-text description. Absent: unchanged.
isPrivatebooleannoNew visibility - true for private. Absent: unchanged.

Response payload

The envelope's data member carries:

FieldTypeRequiredDescription
ownerstringyesUsername of the repository owner (the bearer token's user).
namestringyesURL slug of the repository - the :name segment of every repository route.
displayNamestringyesHuman-readable repository name.
descriptionstring or nullyesFree-text description, or null when the repository has none.
isPrivatebooleanyesTrue when the repository is private (visible to authorized users only).
defaultBranchstringyesName of the default branch.
createdAtstringyesCreation timestamp, ISO 8601.
updatedAtstringyesLast-modification timestamp, ISO 8601.

Example request

curl -X PATCH https://<INSTANCE>.git.eu/api/v0/repos/<USERNAME>/{name} \
  -H "Authorization: Bearer giteu_your_token" \
  -H "Content-Type: application/json" \
  -d '{"displayName":"string"}'

Errors

TypeStatusTitle
unauthorized401Unauthorized
not_found404Not Found
forbidden403Forbidden
validation_failed400Validation Failed
slug_taken409Slug already taken
invalid_slug400Invalid repository name
invalid_description400Invalid description
invalid_visibility400Invalid visibility

DELETE /api/v0/repos/:owner/:name

Permanently deletes a repository and its git data. The deletion is hard and cannot be undone. A successful call returns 204 with an empty body.

PropertyValue
AccessOwnership of the target repository.
Success status204
Success bodyEmpty - this route returns no body.

Path parameters

FieldTypeRequiredDescription
ownerstring (6-42 chars)yesUsername of the repository owner. Letters, digits, ., _, -; starts and ends with a letter or digit; no two of ._- in a row; may not end in .git, .atom or .html; 6-42 characters.
namestring (1-128 chars)yesURL slug of the repository. Letters, digits, ., _, -; starts and ends with a letter or digit; no two of ._- in a row; may not end in .git, .atom or .html; 1-128 characters.

Example request

curl -X DELETE https://<INSTANCE>.git.eu/api/v0/repos/<USERNAME>/{name} \
  -H "Authorization: Bearer giteu_your_token"

Errors

TypeStatusTitle
unauthorized401Unauthorized
not_found404Not Found
forbidden403Forbidden
validation_failed400Validation Failed

Errors

An error body carries an error object in the envelope's error member, served as application/problem+json (the standard problem format, RFC 9457).

FieldTypeRequiredDescription
typestringyesMachine-readable problem type - the stable value to branch on. Never parse the title.
titlestringyesShort human-readable summary, localized.
statusnumberyesHTTP status code, repeated inside the body.
detailstringnoHuman-readable explanation of this specific occurrence.
instancestringnoURI of the specific occurrence.
extensionsobjectnoProblem-specific extra members.

Problem Types

Every problem type this API can return, response-level and per-item alike:

TypeStatusTitle
unauthorized401Unauthorized
validation_failed400Validation Failed
slug_taken409Slug already taken
invalid_slug400Invalid repository name
invalid_branch400Invalid branch name
invalid_visibility400Invalid visibility
invalid_description400Invalid description
disk_init_failed500Repository initialization failed
not_found404Not Found
forbidden403Forbidden