Upload fonts
curl -H "X-Api-Key: $ADMIN_KEY" -F file=@brand-fonts.zip \ http://localhost:9027/v1/fontsimport { openAsBlob } from 'node:fs';
const form = new FormData();form.append('file', await openAsBlob('brand-fonts.zip'), 'brand-fonts.zip');
const response = await fetch('http://localhost:9027/v1/fonts', { method: 'POST', headers: { 'X-Api-Key': process.env.ADMIN_KEY }, body: form,});if (!response.ok) throw new Error(await response.text());console.log(await response.json());import os
import requests
response = requests.post( "http://localhost:9027/v1/fonts", headers={"X-Api-Key": os.environ["ADMIN_KEY"]}, files=[("file", open("brand-fonts.zip", "rb"))],)response.raise_for_status()print(response.json())package main
import ( "bytes" "io" "log" "mime/multipart" "net/http" "os" "path/filepath")
func main() { var body bytes.Buffer form := multipart.NewWriter(&body) attach(form, "file", "brand-fonts.zip") form.Close()
request, err := http.NewRequest("POST", "http://localhost:9027/v1/fonts", &body) if err != nil { log.Fatal(err) } request.Header.Set("X-Api-Key", os.Getenv("ADMIN_KEY")) request.Header.Set("Content-Type", form.FormDataContentType())
response, err := http.DefaultClient.Do(request) if err != nil { log.Fatal(err) } defer response.Body.Close() if response.StatusCode >= 300 { message, _ := io.ReadAll(response.Body) log.Fatalf("%s: %s", response.Status, message) } if _, err := io.Copy(os.Stdout, response.Body); err != nil { log.Fatal(err) }}
// attach adds the file at path to the form as the named field.func attach(form *multipart.Writer, field, path string) { file, err := os.Open(path) if err != nil { log.Fatal(err) } defer file.Close() part, err := form.CreateFormFile(field, filepath.Base(path)) if err != nil { log.Fatal(err) } if _, err := io.Copy(part, file); err != nil { log.Fatal(err) }}Stores fonts for every caller and every replica: a ZIP of TTF, OTF or TTC files,
or one such file. Takes an admin. They are in use on this replica when this
returns, and on the others within syncIntervalSeconds.
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”The multipart form POST /v1/fonts accepts.
object
A ZIP of TTF, OTF or TTC files, or one such file.
Responses
Section titled “Responses”Stored
What an upload stored.
object
A stored font.
object
object
The hex SHA-256 of the file, so storing it twice changes nothing.
RFC 3339.
Files in the ZIP that were left out, and why.
object
In use on this replica now, and on the others within this many seconds.
Example generated
{ "fonts": [ { "faces": [ { "family": "example", "style": "example", "weight": 1 } ], "file": "example", "id": "example", "size": 1, "uploadedAt": "example" } ], "skipped": [ { "file": "example", "reason": "example" } ], "syncIntervalSeconds": 1}Not fonts, or too large
The JSON body of every error response.
object
A stable, machine-readable kind.
What went wrong, for a person.
Example
{ "error": "invalid_request", "message": "unknown step 'teleport'"}Needs an admin, or the store is full
The JSON body of every error response.
object
A stable, machine-readable kind.
What went wrong, for a person.
Example
{ "error": "invalid_request", "message": "unknown step 'teleport'"}RUSTICDOC_STORE is not set
The JSON body of every error response.
object
A stable, machine-readable kind.
What went wrong, for a person.
Example
{ "error": "invalid_request", "message": "unknown step 'teleport'"}The store cannot be reached
The JSON body of every error response.
object
A stable, machine-readable kind.
What went wrong, for a person.
Example
{ "error": "invalid_request", "message": "unknown step 'teleport'"}