| # Web API |
| |
| A registry may host a web API at the location defined in `config.json` to |
| support any of the actions listed below. |
| |
| Cargo includes the `Authorization` header for requests that require |
| authentication. The header value is the API token. The server should respond |
| with a 403 response code if the token is not valid. Users are expected to |
| visit the registry's website to obtain a token, and Cargo can store the token |
| using the [`cargo login`] command, or by passing the token on the |
| command-line. |
| |
| Responses use a 2xx response code for success. |
| Errors should use an appropriate response code, such as 404. |
| Failure |
| responses should have a JSON object with the following structure: |
| |
| ```javascript |
| { |
| // Array of errors to display to the user. |
| "errors": [ |
| { |
| // The error message as a string. |
| "detail": "error message text" |
| } |
| ] |
| } |
| ``` |
| |
| If the response has this structure Cargo will display the detailed message to the user, even if the response code is 200. |
| If the response code indicates an error and the content does not have this structure, Cargo will display to the user a |
| message intended to help debugging the server error. A server returning an `errors` object allows a registry to provide a more |
| detailed or user-centric error message. |
| |
| For backwards compatibility, servers should ignore any unexpected query |
| parameters or JSON fields. If a JSON field is missing, it should be assumed to |
| be null. The endpoints are versioned with the `v1` component of the path, and |
| Cargo is responsible for handling backwards compatibility fallbacks should any |
| be required in the future. |
| |
| Cargo sets the `User-Agent` header for all requests to the Cargo version such |
| as `cargo/1.32.0 (8610973aa 2019-01-02)`. This may be modified by the user in |
| a configuration value. Added in 1.29. |
| |
| Other headers vary by endpoint and are documented below. |
| |
| ## Publish |
| |
| - Endpoint: `/api/v1/crates/new` |
| - Method: PUT |
| - Authorization: Included |
| - Headers: |
| - `Content-Type`: `application/octet-stream` |
| - `Accept`: `application/json` |
| - Body: Included (see below) |
| |
| The publish endpoint is used to publish a new version of a crate. The server |
| should validate the crate, make it available for download, and add it to the |
| index. |
| |
| It is not required for the index to be updated before the successful response is sent. |
| After a successful response, Cargo will poll the index for a short period of time to identify that the new crate has been added. |
| If the crate does not appear in the index after a short period of time, then Cargo will display a warning letting the user know that the new crate is not yet available. |
| |
| The body of the data sent by Cargo is: |
| |
| - 32-bit unsigned little-endian integer of the length of JSON data. |
| - Metadata of the package as a JSON object. |
| - 32-bit unsigned little-endian integer of the length of the `.crate` file. |
| - The `.crate` file. |
| |
| The following is a commented example of the JSON object. Some notes of some |
| restrictions imposed by [crates.io] are included only to illustrate some |
| suggestions on types of validation that may be done, and should not be |
| considered as an exhaustive list of restrictions [crates.io] imposes. |
| |
| ```javascript |
| { |
| // The name of the package. |
| "name": "foo", |
| // The version of the package being published. |
| "vers": "0.1.0", |
| // Array of direct dependencies of the package. |
| "deps": [ |
| { |
| // Name of the dependency. |
| // If the dependency is renamed from the original package name, |
| // this is the original name. The new package name is stored in |
| // the `explicit_name_in_toml` field. |
| "name": "rand", |
| // The semver requirement for this dependency. |
| "version_req": "^0.6", |
| // Array of features (as strings) enabled for this dependency. |
| "features": ["i128_support"], |
| // Boolean of whether or not this is an optional dependency. |
| "optional": false, |
| // Boolean of whether or not default features are enabled. |
| "default_features": true, |
| // The target platform for the dependency. |
| // null if not a target dependency. |
| // Otherwise, a string such as "cfg(windows)". |
| "target": null, |
| // The dependency kind. |
| // "dev", "build", or "normal". |
| "kind": "normal", |
| // The URL of the index of the registry where this dependency is |
| // from as a string. If not specified or null, it is assumed the |
| // dependency is in the current registry. |
| "registry": null, |
| // If the dependency is renamed, this is a string of the new |
| // package name. If not specified or null, this dependency is not |
| // renamed. |
| "explicit_name_in_toml": null, |
| } |
| ], |
| // Set of features defined for the package. |
| // Each feature maps to an array of features or dependencies it enables. |
| // Cargo does not impose limitations on feature names, but crates.io |
| // requires alphanumeric ASCII, `_` or `-` characters. |
| "features": { |
| "extras": ["rand/simd_support"] |
| }, |
| // List of strings of the authors. |
| // May be empty. |
| "authors": ["Alice <a@example.com>"], |
| // Description field from the manifest. |
| // May be null. crates.io requires at least some content. |
| "description": null, |
| // String of the URL to the website for this package's documentation. |
| // May be null. |
| "documentation": null, |
| // String of the URL to the website for this package's home page. |
| // May be null. |
| "homepage": null, |
| // String of the content of the README file. |
| // May be null. |
| "readme": null, |
| // String of a relative path to a README file in the crate. |
| // May be null. |
| "readme_file": null, |
| // Array of strings of keywords for the package. |
| "keywords": [], |
| // Array of strings of categories for the package. |
| "categories": [], |
| // String of the license for the package. |
| // May be null. crates.io requires either `license` or `license_file` to be set. |
| "license": null, |
| // String of a relative path to a license file in the crate. |
| // May be null. |
| "license_file": null, |
| // String of the URL to the website for the source repository of this package. |
| // May be null. |
| "repository": null, |
| // Optional object of "status" badges. Each value is an object of |
| // arbitrary string to string mappings. |
| // crates.io has special interpretation of the format of the badges. |
| "badges": { |
| "travis-ci": { |
| "branch": "master", |
| "repository": "rust-lang/cargo" |
| } |
| }, |
| // The `links` string value from the package's manifest, or null if not |
| // specified. This field is optional and defaults to null. |
| "links": null, |
| // The minimal supported Rust version (optional) |
| // This must be a valid version requirement without an operator (e.g. no `=`) |
| "rust_version": null |
| } |
| ``` |
| |
| A successful response includes the JSON object: |
| |
| ```javascript |
| { |
| // Optional object of warnings to display to the user. |
| "warnings": { |
| // Array of strings of categories that are invalid and ignored. |
| "invalid_categories": [], |
| // Array of strings of badge names that are invalid and ignored. |
| "invalid_badges": [], |
| // Array of strings of arbitrary warnings to display to the user. |
| "other": [] |
| } |
| } |
| ``` |
| |
| ## Yank |
| |
| - Endpoint: `/api/v1/crates/{crate_name}/{version}/yank` |
| - Method: DELETE |
| - Authorization: Included |
| - Headers: |
| - `Accept`: `application/json` |
| - Body: None |
| |
| The yank endpoint will set the `yank` field of the given version of a crate to |
| `true` in the index. |
| |
| A successful response includes the JSON object: |
| |
| ```javascript |
| { |
| // Indicates the yank succeeded, always true. |
| "ok": true, |
| } |
| ``` |
| |
| ## Unyank |
| |
| - Endpoint: `/api/v1/crates/{crate_name}/{version}/unyank` |
| - Method: PUT |
| - Authorization: Included |
| - Headers: |
| - `Accept`: `application/json` |
| - Body: None |
| |
| The unyank endpoint will set the `yank` field of the given version of a crate |
| to `false` in the index. |
| |
| A successful response includes the JSON object: |
| |
| ```javascript |
| { |
| // Indicates the unyank succeeded, always true. |
| "ok": true, |
| } |
| ``` |
| |
| ## Owners |
| |
| Cargo does not have an inherent notion of users and owners, but it does |
| provide the `owner` command to assist managing who has authorization to |
| control a crate. It is up to the registry to decide exactly how users and |
| owners are handled. See the [publishing documentation] for a description of |
| how [crates.io] handles owners via GitHub users and teams. |
| |
| ### Owners: List |
| |
| - Endpoint: `/api/v1/crates/{crate_name}/owners` |
| - Method: GET |
| - Authorization: Included |
| - Headers: |
| - `Accept`: `application/json` |
| - Body: None |
| |
| The owners endpoint returns a list of owners of the crate. |
| |
| A successful response includes the JSON object: |
| |
| ```javascript |
| { |
| // Array of owners of the crate. |
| "users": [ |
| { |
| // Unique unsigned 32-bit integer of the owner. |
| "id": 70, |
| // The unique username of the owner. |
| "login": "github:rust-lang:core", |
| // Name of the owner. |
| // This is optional and may be null. |
| "name": "Core", |
| } |
| ] |
| } |
| ``` |
| |
| ### Owners: Add |
| |
| - Endpoint: `/api/v1/crates/{crate_name}/owners` |
| - Method: PUT |
| - Authorization: Included |
| - Headers: |
| - `Content-Type`: `application/json` |
| - `Accept`: `application/json` |
| - Body: Included (see below) |
| |
| A PUT request will send a request to the registry to add a new owner to a |
| crate. It is up to the registry how to handle the request. For example, |
| [crates.io] sends an invite to the user that they must accept before being |
| added. |
| |
| The request should include the following JSON object: |
| |
| ```javascript |
| { |
| // Array of `login` strings of owners to add. |
| "users": ["login_name"] |
| } |
| ``` |
| |
| A successful response includes the JSON object: |
| |
| ```javascript |
| { |
| // Indicates the add succeeded, always true. |
| "ok": true, |
| // A string to be displayed to the user. |
| "msg": "user ehuss has been invited to be an owner of crate cargo" |
| } |
| ``` |
| |
| ### Owners: Remove |
| |
| - Endpoint: `/api/v1/crates/{crate_name}/owners` |
| - Method: DELETE |
| - Authorization: Included |
| - Headers: |
| - `Content-Type`: `application/json` |
| - `Accept`: `application/json` |
| - Body: Included (see below) |
| |
| A DELETE request will remove an owner from a crate. The request should include |
| the following JSON object: |
| |
| ```javascript |
| { |
| // Array of `login` strings of owners to remove. |
| "users": ["login_name"] |
| } |
| ``` |
| |
| A successful response includes the JSON object: |
| |
| ```javascript |
| { |
| // Indicates the remove succeeded, always true. |
| "ok": true |
| // A string to be displayed to the user. Currently ignored by cargo. |
| "msg": "owners successfully removed", |
| } |
| ``` |
| |
| ## Search |
| |
| - Endpoint: `/api/v1/crates` |
| - Method: GET |
| - Authorization: Not Included |
| - Headers: |
| - `Accept`: `application/json` |
| - Body: None |
| - Query Parameters: |
| - `q`: The search query string. |
| - `per_page`: Number of results, default 10, max 100. |
| |
| The search request will perform a search for crates, using criteria defined on |
| the server. |
| |
| A successful response includes the JSON object: |
| |
| ```javascript |
| { |
| // Array of results. |
| "crates": [ |
| { |
| // Name of the crate. |
| "name": "rand", |
| // The highest version available. |
| "max_version": "0.6.1", |
| // Textual description of the crate. |
| "description": "Random number generators and other randomness functionality.\n", |
| } |
| ], |
| "meta": { |
| // Total number of results available on the server. |
| "total": 119 |
| } |
| } |
| ``` |
| |
| ## Login |
| |
| - Endpoint: `/me` |
| |
| The "login" endpoint is not an actual API request. It exists solely for the |
| [`cargo login`] command to display a URL to instruct a user to visit in a web |
| browser to log in and retrieve an API token. |
| |
| [`cargo login`]: ../commands/cargo-login.md |
| [`cargo package`]: ../commands/cargo-package.md |
| [`cargo publish`]: ../commands/cargo-publish.md |
| [alphanumeric]: ../../std/primitive.char.html#method.is_alphanumeric |
| [config]: config.md |
| [crates.io]: https://crates.io/ |
| [publishing documentation]: publishing.md#cargo-owner |