Skip to main content

File Service

The File Service owns all collaborative resources in Typograph: teams, projects, templates, media and fonts, plus sharing, invites, comments, favorites, trash, and search. The gateway routes everything under /v1/file/*.

Base URL: /v1/file/

Scopes: file (full), file:read, file:write, file:delete. All File Service endpoints require a user token.

Path structure

File Service paths follow a "list-by-parent, item-by-id" pattern. Collections are listed and created under their owning parent (projects under teams, templates under projects, media/uploads/fonts under projects), but individual resources are addressed by their own top-level ID once created. Top-level GET /v1/file/teams is an exception — it's scoped to the authenticated user's organization.

Teams

EndpointMethodScopes
/v1/file/teamsGETfile / file:read
/v1/file/teamsPOSTfile / file:write
/v1/file/teams/{id}GETfile / file:read
/v1/file/teams/{id}PATCHfile / file:write
/v1/file/teams/{id}DELETEfile / file:delete
/v1/file/teams/{teamId}/contactsGETfile / file:read
/v1/file/organizations/{organizationId}/teamsGETfile / file:read
curl https://api.typograph.nl/v1/file/teams \
-H "Authorization: Bearer $USER_TOKEN"

List responses follow standard pagination.

Projects

Projects are team-scoped — there's no top-level "list all projects" endpoint. Create and list projects on a specific team; once you have a project ID you can read, update, and delete it directly.

EndpointMethodScopes
/v1/file/teams/{teamId}/projectsGETfile / file:read
/v1/file/teams/{teamId}/projectsPOSTfile / file:write
/v1/file/projects/{id}GETfile / file:read
/v1/file/projects/{id}PATCHfile / file:write
/v1/file/projects/{id}DELETEfile / file:delete
/v1/file/projects/{projectId}/templatesGET, POSTfile:read / file:write
/v1/file/projects/{projectId}/uploadsGET, POSTfile:read / file:write
/v1/file/projects/{projectId}/uploads/{id}PATCHfile:write
/v1/file/projects/{projectId}/mediaGETfile:read
/v1/file/projects/{projectId}/media/presigned-urlsPOSTfile:read
/v1/file/projects/{projectId}/fontsGETfile:read
/v1/file/projects/{projectId}/fonts/presigned-urlsPOSTfile:read
curl -X POST https://api.typograph.nl/v1/file/teams/019b.../projects \
-H "Authorization: Bearer $USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "name": "Q4 Campaign" }'

Templates

Templates are the Typograph document files that the editor opens and the publisher renders. Templates are project-scoped on create/list — once you have a template ID you can read and update it directly.

EndpointMethodScopes
/v1/file/projects/{projectId}/templatesGETfile / file:read
/v1/file/projects/{projectId}/templatesPOSTfile / file:write
/v1/file/templates/{id}GETfile / file:read
/v1/file/templates/{id}PATCHfile / file:write
/v1/file/templates/{id}DELETEfile / file:delete
/v1/file/templates/{id}/touchPATCHfile:write
/v1/file/templates/{id}/{fileType}/presigned-urlPOSTfile:write

fileType is one of thumbnail or document. The touch endpoint bumps the "last modified" timestamp without changing content — the editor calls it on open to drive recency lists. DELETE /templates/{id} soft-deletes a template (?action=delete) or restores it (?action=undelete); soft-deleted templates surface in the user's trash flow (see Trash) and are permanently removed — including their files in storage — by the scheduled deletion job once the retention window has passed.

Premade templates

The premade template catalog is a global, read-only set of starter templates curated by Typograph. Unlike project templates, the catalog is identical for every user and is not project-scoped. Items are addressed by a URL-safe code (lowercase letters, digits, hyphens) rather than a UUID.

EndpointMethodScopes
/v1/file/premade-templatesGETfile / file:read
/v1/file/premade-templates/categoriesGETfile / file:read
/v1/file/premade-templates/{code}GETfile / file:read

The list endpoint accepts limit (max 100, default 50), offset, category (filter by category code), and featured (boolean) query parameters. List responses are wrapped as { "results": [...], "total": <int> }.

Template comments

EndpointMethodScopes
/v1/file/templates/{templateId}/commentsGETfile:read
/v1/file/templates/{templateId}/commentsPOSTfile:write
/v1/file/templates/{templateId}/comments/{commentId}PUTfile:write
/v1/file/templates/{templateId}/comments/{commentId}DELETEfile:delete
/v1/file/templates/{templateId}/comments/{commentId}/resolvePATCHfile:write
/v1/file/templates/{templateId}/comments/{commentId}/repliesGET, POSTfile:read / file:write
/v1/file/templates/{templateId}/comments/{commentId}/replies/{replyId}PUTfile:write
/v1/file/templates/{templateId}/comments/{commentId}/replies/{replyId}DELETEfile:delete

Sharing: Invites, Roles, Permissions

Sharing is resource-scoped: you invite someone to a specific team, project, or template. The resource type is part of the URL.

EndpointMethodScopes
/v1/file/{resourceType}/{resourceId}/permissionsGETfile:read
/v1/file/{resourceType}/{resourceId}/invitesGET, POSTfile:read / file:write
/v1/file/{resourceType}/{resourceId}/invites/{id}GETfile:read
/v1/file/{resourceType}/{resourceId}/invites/{id}PATCHfile:write
/v1/file/{resourceType}/{resourceId}/invites/{id}DELETEfile:delete
/v1/file/{resourceType}/{resourceId}/roles/{id}PATCHfile:write
/v1/file/{resourceType}/{resourceId}/roles/{id}DELETEfile:delete

resourceType is one of team, project, or template.

curl -X POST https://api.typograph.nl/v1/file/template/019b.../invites \
-H "Authorization: Bearer $USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "email": "colleague@example.com", "role": "editor" }'

The authoritative list of roles and their capabilities lives on the Identity Service — see Identity Service.

Favorites, Shared, Trash, Search, Recents

EndpointMethodScopes
/v1/file/favosGETfile / file:read
/v1/file/favosPUTfile / file:write
/v1/file/shared/projectsGETfile / file:read
/v1/file/shared/templatesGETfile / file:read
/v1/file/trashGETfile / file:read
/v1/file/searchGETfile / file:read
/v1/file/recent/searchedGETfile / file:read
/v1/file/recent/templatesGETfile / file:read

PUT /v1/file/favos toggles the favorite state for a resource (pass the resource type and id in the body).

Users, Roles & Invites (Current User)

EndpointMethodScopesNotes
/v1/file/usersPATCHfile / file:writeUpdates the authenticated user's profile in the file service.
/v1/file/users/{id}GETfile / file:readFetch a specific user by UUID.
/v1/file/users/me/invitesGETfile / file:readList invites addressed to the current user.
/v1/file/rolesGETfile / file:readCatalog of resource roles (owner/editor/commenter/viewer).

Notifications

EndpointMethodScopes
/v1/file/notificationsGETfile / file:read
/v1/file/notificationsPATCHfile / file:write
/v1/file/notifications/{id}PATCHfile / file:write

Mark a single notification read/unread with PATCH /notifications/{id}. Mark all notifications read in one call with PATCH /notifications (no body fields required).

Uploads

Large uploads use presigned URLs — you request one from the File Service, then PUT the file bytes directly to cloud storage, bypassing the API. The same pattern applies for project media, project fonts, and template thumbnails/documents (endpoints listed in the relevant sections above).

Flow:

POST /v1/file/projects/{projectId}/media/presigned-urls   # get upload URLs
PUT <signed_url> # upload bytes to R2/S3
PATCH /v1/file/projects/{projectId}/uploads/{id} # finalize metadata

Error Responses

Standard envelope (see API Overview → Error Handling):

StatusErrorDescription
401unauthorizedMissing or invalid token
403access_deniedMissing scope or resource permission
404not_foundResource does not exist or not accessible to caller
409conflictDuplicate slug / concurrent edit
422validation_errorField validation failed
{
"error": "validation_error",
"error_description": "Request validation failed",
"request_id": "019397ab-cdef-7890-abcd-ef1234567890",
"details": [
{ "field": "name", "code": "required", "message": "The name field is required." }
]
}