Перейти к содержимому

REST и GraphQL API

Всё, что делает веб-приложение, идёт через тот же публичный API, который доступен и вам. Входов два — REST для автоматизации и GraphQL, которым пользуется само приложение, — и оба стоят за одной и той же авторизацией и одними и теми же проверками прав.

Базовый адрес: https://api.ownlate.com

Учётные данныеКак выглядятДля чего
Ключ APIown_…Вызовы сервер-сервер, CI, скрипты
SDK-токенsdk_…Браузерный SDK, только один проект
Токен доступа OAuthнепрозрачныйMCP-сервер и сторонние приложения
Cookie сессииВеб-приложение в вашем браузере

Ключ передаётся как bearer-токен:

Окно терминала
curl "https://api.ownlate.com/v1/workspaces" \
-H "Authorization: Bearer $OWNLATE_API_KEY"

Ключи создаются в разделе Профиль → Ключи API. Ключ показывается один раз, при создании, дальше видно только его префикс. У каждого ключа есть:

  • Области — коды прав, которыми он может пользоваться; они только сужают то, что есть у вас, и никогда не расширяют.
  • Необязательный срок — после которого ключ перестаёт работать.

Отзыв ключа действует немедленно. Сами коды прав — в разделе Участники и доступ.

Для каждого вызова сервер сначала выясняет, о каком рабочем пространстве речь, затем сверяет с ним то, что есть у вызывающего:

  • Пространство берётся из пути. Строка запроса и тело при этом не рассматриваются, поэтому ручка, в пути которой пространство не названо, отвечает Workspace ID is required, а не угадывает.
  • Ключ API или токен OAuth сужают дальше: право вне их областей или пространство вне тех, для которых их выдали, отклоняются ещё до обращения к пространству.
  • Анонимный вызывающий получает то же, что увидел бы viewer, — и не больше.
  • Открытый проект вдобавок принимает предложения от любого вошедшего.

Неудачи возвращаются в JSON, статус продублирован в теле:

{ "message": "Forbidden", "error": "Forbidden", "statusCode": 403 }
СтатусЧто значит
400Запрос не прошёл валидацию
401Учётных данных нет либо они больше не годятся
403Вы опознаны, но делать это вам нельзя
404Нет такого объекта либо нет такого маршрута
409Объект не в том состоянии — например, утверждение уже утверждённого

Тело запроса ограничено 1 МБ. Файлы больше — разбивайте загрузку по файлам.

Сгенерированный документ OpenAPI отдаётся по адресу /swagger-json, а приложение рисует его на platform.ownlate.com/docs/swagger. Он собирается из работающего сервера, поэтому не расходится с тем, что выкачено.

МетодПуть
GET POST/v1/workspaces
GET PUT/v1/workspaces/{workspaceId}
GET/v1/workspaces/{workspaceId}/audit-log
POST/v1/workspaces/{workspaceId}/sync-word-usage
GET/v1/workspaces/{workspaceId}/users/me/permissions
GET POST/v1/workspaces/{workspaceId}/members
DELETE/v1/workspaces/{workspaceId}/members/{userId}
GET/v1/workspaces/users/lookup
GET PUT/v1/workspaces/levels/{level}
GET POST/v1/workspaces/api-keys
DELETE/v1/workspaces/api-keys/{keyId}
GET/v1/users/me
МетодПуть
GET POST/v1/workspaces/{workspaceId}/projects
GET PUT DELETE/v1/workspaces/{workspaceId}/projects/{id}
PUT/v1/workspaces/{workspaceId}/projects/{id}/restore
DELETE/v1/workspaces/{workspaceId}/projects/{id}/permanent

DELETE архивирует проект, permanent уничтожает уже архивный.

МетодПуть
GET POST/v1/workspaces/{workspaceId}/translation-files
POST/v1/workspaces/{workspaceId}/translation-files/upload
PUT DELETE/v1/workspaces/{workspaceId}/translation-files/{id}
POST/v1/workspaces/{workspaceId}/translation-files/rename-folder
POST/v1/workspaces/{workspaceId}/translation-files/merge-duplicates
МетодПуть
GET POST/v1/workspaces/{workspaceId}/segments
GET DELETE/v1/workspaces/{workspaceId}/segments/{id}
PUT/v1/workspaces/{workspaceId}/segments/{id}/translate
PUT/v1/workspaces/{workspaceId}/segments/{id}/draft
PUT/v1/workspaces/{workspaceId}/segments/{id}/source-text
PUT/v1/workspaces/{workspaceId}/segments/{id}/translations/{language}/review
PUT/v1/workspaces/{workspaceId}/segments/{id}/translations/{language}/approve
PUT/v1/workspaces/{workspaceId}/segments/{id}/translations/{language}/reject
POST/v1/workspaces/{workspaceId}/segments/{id}/auto-translate
GET/v1/workspaces/{workspaceId}/segments/{id}/qa
POST/v1/workspaces/{workspaceId}/segments/approve-all
POST/v1/workspaces/{workspaceId}/segments/reject-all
POST/v1/workspaces/{workspaceId}/segments/pre-translate
GET/v1/workspaces/{workspaceId}/segments/progress
GET/v1/workspaces/{workspaceId}/segments/analytics
GET/v1/workspaces/{workspaceId}/segments/by-keys
GET/v1/workspaces/{workspaceId}/segments/translation-memory
GET/v1/workspaces/{workspaceId}/segments/export
GET/v1/workspaces/{workspaceId}/segments/export-zip
МетодПуть
GET POST/v1/workspaces/{workspaceId}/glossary
PUT DELETE/v1/workspaces/{workspaceId}/glossary/{id}
GET/v1/workspaces/{workspaceId}/glossary/matches
GET POST/v1/workspaces/{workspaceId}/comments
DELETE/v1/workspaces/{workspaceId}/comments/{id}
GET/v1/workspaces/{workspaceId}/translation-history/{segmentId}
МетодПуть
GET POST/v1/workspaces/{workspaceId}/releases
DELETE/v1/workspaces/{workspaceId}/releases/{id}
GET/v1/workspaces/{workspaceId}/releases/distribution
POST/v1/workspaces/{workspaceId}/releases/distribution/regenerate
МетодПуть
POST/v1/workspaces/{workspaceId}/integrations
GET/v1/workspaces/{workspaceId}/integrations/by-project/{projectId}
GET PUT DELETE/v1/workspaces/{workspaceId}/integrations/{id}
PATCH/v1/workspaces/{workspaceId}/integrations/{id}/activate
PATCH/v1/workspaces/{workspaceId}/integrations/{id}/pause
PATCH/v1/workspaces/{workspaceId}/integrations/{id}/sync
PATCH/v1/workspaces/{workspaceId}/integrations/{id}/test
POST/v1/workspaces/{workspaceId}/integrations/test-direct
POST/v1/workspaces/{workspaceId}/integrations/{id}/create-pr
МетодПуть
GET/v1/plans
GET/v1/payment/providers
GET/v1/workspaces/{workspaceId}/subscription
PUT/v1/workspaces/{workspaceId}/subscription/plan
POST/v1/workspaces/{workspaceId}/subscription/checkout
POST/v1/workspaces/{workspaceId}/subscription/portal
МетодПуть
GET POST/v1/languages
DELETE/v1/languages/{code}

Им не нужны никакие учётные данные. Они обслуживают публичные проекты и OTA-раздачи.

МетодПутьЧто отдаёт
GET/public/v1/projectsПубличные проекты пространства
GET/public/v1/projects/{id}Один публичный проект
GET/public/v1/segments/progressПрогресс публичного проекта
GET/public/v1/segments/translations-mapВсе переводы публичного проекта, сгруппированные по файлу и языку
GET/public/v1/ota/{accessKey}/manifestВерсия последнего релиза и языки
GET/public/v1/ota/{accessKey}/bundlesБандл по всем языкам
GET/public/v1/ota/{accessKey}/bundles/{language}Бандл одного языка
GET/public/v1/plansТарифы с ценами
GET/public/v1/workspaces/{workspaceId}Публичные сведения о пространстве

The SDK endpoints — /public/v1/sdk/segments and /public/v1/sdk/segments/{id}/translations/{lang} — need an SDK token rather than an API key. See SDK and clients.

Ручки SDK — /public/v1/sdk/segments и /public/v1/sdk/segments/{id}/translations/{lang} — требуют SDK-токен, а не ключ API. См. SDK и клиенты.

POST /graphql несёт те же операции, которыми пользуется веб-приложение, а это больше, чем выставляет REST: приглашения, задачи, предложения, уведомления, правила QA, SDK-токены, записи памяти переводов и аналитические запросы.

Окно терминала
curl -X POST https://api.ownlate.com/graphql \
-H "Authorization: Bearer $OWNLATE_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"query":"query($id:ID!){ project(id:$id){ name progress { language progress } } }","variables":{"id":"…"}}'

Две вещи, которые стоит знать до того, как направлять туда клиента:

  • Тип содержимого важен. Запрос, который мог бы прийти из HTML-формы — application/x-www-form-urlencoded, multipart/form-data или text/plain, — отклоняется как возможный межсайтовый, если он не называет операцию в заголовке x-apollo-operation-name. Отправляйте application/json, и вопрос не возникнет.
  • Права выводятся из аргументов. Передавайте workspaceId там, где его просит схема, в том числе внутри объектов input; мутацию, где его нет, авторизовать невозможно.