Files

986 lines
25 KiB
YAML

openapi: 3.1.0
info:
title: Open Shorebird Self-Hosted API
version: 0.1.0
description: |
OpenAPI contract for the self-hosted Shorebird-compatible server in this
workspace. The API preserves the route shape expected by the open CLI,
CodePush client, and updater while using local/self-hosted services.
servers:
- url: http://localhost:8080
security:
- bearerAuth: []
tags:
- name: auth
- name: apps
- name: organizations
- name: releases
- name: patches
- name: devices
- name: diagnostics
- name: admin
paths:
/health:
get:
operationId: getHealth
security: []
tags: [diagnostics]
responses:
'200':
description: Server health and backend status.
content:
application/json:
schema:
type: object
additionalProperties: true
/openapi.yaml:
get:
operationId: getOpenAPISpec
security: []
tags: [diagnostics]
responses:
'200':
description: This OpenAPI document.
content:
application/yaml:
schema:
type: string
/api/v1/openapi.yaml:
get:
operationId: getOpenAPISpecV1
security: []
tags: [diagnostics]
responses:
'200':
description: This OpenAPI document served from a versioned path.
content:
application/yaml:
schema:
type: string
/auth/token:
post:
operationId: createAuthToken
security: []
tags: [auth]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/LoginRequest'
responses:
'200':
description: JWT and user metadata.
content:
application/json:
schema:
$ref: '#/components/schemas/AuthTokenResponse'
/auth/register:
post:
operationId: createAuthUser
security: []
tags: [auth]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RegisterRequest'
responses:
'200':
description: Registered user.
content:
application/json:
schema:
$ref: '#/components/schemas/PrivateUser'
/auth/refresh:
post:
operationId: refreshAuthToken
tags: [auth]
responses:
'200':
description: Refreshed JWT.
content:
application/json:
schema:
$ref: '#/components/schemas/AuthTokenResponse'
/auth/public-settings:
get:
operationId: getAuthPublicSettings
security: []
tags: [auth]
responses:
'200':
description: Public registration and SSO settings.
content:
application/json:
schema:
type: object
additionalProperties: true
/api/v1/patches/check:
post:
operationId: patchCheck
security: []
tags: [devices]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PatchCheckRequest'
responses:
'200':
description: Device patch check result.
content:
application/json:
schema:
$ref: '#/components/schemas/PatchCheckResponse'
/api/v1/patches/events:
post:
operationId: patchEvents
security: []
tags: [devices]
requestBody:
required: true
content:
application/json:
schema:
type: object
additionalProperties: true
responses:
'204':
description: Event accepted.
/api/v1/users/me:
get:
operationId: getCurrentUser
tags: [auth]
responses:
'200':
description: Current user.
content:
application/json:
schema:
$ref: '#/components/schemas/PrivateUser'
patch:
operationId: updateCurrentUserPassword
tags: [auth]
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [current_password, new_password]
properties:
current_password:
type: string
new_password:
type: string
responses:
'200':
description: Password updated.
/api/v1/users:
post:
operationId: createUser
tags: [auth]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateUserRequest'
responses:
'200':
description: Created user.
content:
application/json:
schema:
$ref: '#/components/schemas/PrivateUser'
/api/v1/apps:
get:
operationId: getApps
tags: [apps]
responses:
'200':
description: Apps visible to the current user.
content:
application/json:
schema:
type: object
required: [apps]
properties:
apps:
type: array
items:
$ref: '#/components/schemas/App'
post:
operationId: createApp
tags: [apps]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateAppRequest'
responses:
'200':
description: Created app.
content:
application/json:
schema:
$ref: '#/components/schemas/App'
/api/v1/apps/{appId}:
delete:
operationId: deleteApp
tags: [apps]
parameters:
- $ref: '#/components/parameters/AppId'
responses:
'204':
description: App deleted.
/api/v1/apps/{appId}/transfer:
patch:
operationId: transferApp
tags: [apps]
parameters:
- $ref: '#/components/parameters/AppId'
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [organization_id]
properties:
organization_id:
type: integer
responses:
'200':
description: Transferred app.
/api/v1/apps/{appId}/channels:
get:
operationId: getChannels
tags: [apps]
parameters:
- $ref: '#/components/parameters/AppId'
responses:
'200':
description: App channels.
content:
application/json:
schema:
type: object
required: [channels]
properties:
channels:
type: array
items:
$ref: '#/components/schemas/Channel'
post:
operationId: createChannel
tags: [apps]
parameters:
- $ref: '#/components/parameters/AppId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateChannelRequest'
responses:
'200':
description: Created channel.
/api/v1/apps/{appId}/releases:
get:
operationId: getReleases
tags: [releases]
parameters:
- $ref: '#/components/parameters/AppId'
responses:
'200':
description: App releases.
content:
application/json:
schema:
type: object
required: [releases]
properties:
releases:
type: array
items:
$ref: '#/components/schemas/Release'
post:
operationId: createRelease
tags: [releases]
parameters:
- $ref: '#/components/parameters/AppId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateReleaseRequest'
responses:
'200':
description: Created release.
content:
application/json:
schema:
$ref: '#/components/schemas/Release'
/api/v1/apps/{appId}/releases/{releaseId}:
patch:
operationId: updateRelease
tags: [releases]
parameters:
- $ref: '#/components/parameters/AppId'
- $ref: '#/components/parameters/ReleaseId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateReleaseRequest'
responses:
'200':
description: Updated release.
delete:
operationId: deleteRelease
tags: [releases]
parameters:
- $ref: '#/components/parameters/AppId'
- $ref: '#/components/parameters/ReleaseId'
responses:
'204':
description: Release deleted.
/api/v1/apps/{appId}/releases/{releaseId}/artifacts:
get:
operationId: getReleaseArtifacts
tags: [releases]
parameters:
- $ref: '#/components/parameters/AppId'
- $ref: '#/components/parameters/ReleaseId'
responses:
'200':
description: Release artifacts.
content:
application/json:
schema:
type: object
additionalProperties: true
post:
operationId: createReleaseArtifact
tags: [releases]
parameters:
- $ref: '#/components/parameters/AppId'
- $ref: '#/components/parameters/ReleaseId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateReleaseArtifactRequest'
responses:
'200':
description: Uploaded release artifact metadata.
/api/v1/apps/{appId}/patches:
post:
operationId: createPatch
tags: [patches]
parameters:
- $ref: '#/components/parameters/AppId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreatePatchRequest'
responses:
'200':
description: Created patch.
content:
application/json:
schema:
$ref: '#/components/schemas/Patch'
/api/v1/apps/{appId}/patches/{patchId}:
patch:
operationId: updatePatch
tags: [patches]
parameters:
- $ref: '#/components/parameters/AppId'
- $ref: '#/components/parameters/PatchId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdatePatchRequest'
responses:
'200':
description: Updated patch.
/api/v1/apps/{appId}/patches/{patchId}/artifacts:
post:
operationId: createPatchArtifact
tags: [patches]
parameters:
- $ref: '#/components/parameters/AppId'
- $ref: '#/components/parameters/PatchId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreatePatchArtifactRequest'
responses:
'200':
description: Uploaded patch artifact metadata.
/api/v1/apps/{appId}/releases/{releaseId}/patches:
get:
operationId: getReleasePatches
tags: [patches]
parameters:
- $ref: '#/components/parameters/AppId'
- $ref: '#/components/parameters/ReleaseId'
responses:
'200':
description: Patches for a release.
content:
application/json:
schema:
type: object
required: [patches]
properties:
patches:
type: array
items:
$ref: '#/components/schemas/Patch'
/api/v1/apps/{appId}/patches/promote:
post:
operationId: promotePatch
tags: [patches]
parameters:
- $ref: '#/components/parameters/AppId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PromotePatchRequest'
responses:
'200':
description: Promoted patch.
/api/v1/apps/{appId}/patches/rollback:
post:
operationId: rollbackPatch
tags: [patches]
parameters:
- $ref: '#/components/parameters/AppId'
requestBody:
required: true
content:
application/json:
schema:
type: object
additionalProperties: true
responses:
'200':
description: Rolled back patch.
/api/v1/organizations:
get:
operationId: getOrganizations
tags: [organizations]
responses:
'200':
description: Organizations.
content:
application/json:
schema:
type: object
required: [organizations]
properties:
organizations:
type: array
items:
$ref: '#/components/schemas/Organization'
post:
operationId: createOrganization
tags: [organizations]
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [name]
properties:
name:
type: string
organization_type:
type: string
responses:
'200':
description: Created organization.
/api/v1/organizations/{orgId}/users:
get:
operationId: getOrganizationUsers
tags: [organizations]
parameters:
- $ref: '#/components/parameters/OrgId'
responses:
'200':
description: Organization users.
content:
application/json:
schema:
type: object
required: [users]
properties:
users:
type: array
items:
$ref: '#/components/schemas/OrganizationUser'
post:
operationId: updateOrganizationUser
tags: [organizations]
parameters:
- $ref: '#/components/parameters/OrgId'
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [email, role]
properties:
email:
type: string
role:
type: string
responses:
'200':
description: Organization user role updated.
/api/v1/apps/{appId}/metrics/active-hours:
get:
operationId: getActiveHours
tags: [apps]
parameters:
- $ref: '#/components/parameters/AppId'
responses:
'200':
description: Active hour metrics.
/api/v1/apps/{appId}/metrics/unique-users:
get:
operationId: getUniqueUsers
tags: [apps]
parameters:
- $ref: '#/components/parameters/AppId'
responses:
'200':
description: Unique user metrics.
/api/v1/apps/{appId}/metrics/version-distribution:
get:
operationId: getVersionDistribution
tags: [apps]
parameters:
- $ref: '#/components/parameters/AppId'
responses:
'200':
description: Version distribution metrics.
/api/v1/apps/{appId}/metrics/patch-adoption:
get:
operationId: getPatchAdoption
tags: [apps]
parameters:
- $ref: '#/components/parameters/AppId'
responses:
'200':
description: Patch adoption metrics.
/api/v1/diagnostics/gcp_upload:
get:
operationId: getGCPUploadSpeedTestURL
tags: [diagnostics]
responses:
'200':
description: Upload speed-test URL.
/api/v1/diagnostics/gcp_download:
get:
operationId: getGCPDownloadSpeedTestURL
tags: [diagnostics]
responses:
'200':
description: Download speed-test URL.
/api/v1/admin/users:
get:
operationId: listAdminUsers
tags: [admin]
responses:
'200':
description: Admin user list.
/api/v1/admin/users/{userId}/verify-email:
post:
operationId: verifyAdminUserEmail
tags: [admin]
parameters:
- $ref: '#/components/parameters/UserId'
responses:
'200':
description: Email marked verified.
/api/v1/admin/users/{userId}/admin:
post:
operationId: setAdminUser
tags: [admin]
parameters:
- $ref: '#/components/parameters/UserId'
responses:
'200':
description: Admin flag updated.
/api/v1/admin/settings:
get:
operationId: getAdminSettings
tags: [admin]
responses:
'200':
description: Registration and SSO settings.
put:
operationId: updateAdminSettings
tags: [admin]
requestBody:
required: true
content:
application/json:
schema:
type: object
additionalProperties: true
responses:
'200':
description: Settings updated.
/api/v1/admin/patches/{patchId}/target-devices:
get:
operationId: getPatchTargetDevices
tags: [admin]
parameters:
- $ref: '#/components/parameters/PatchId'
responses:
'200':
description: Targeted device IDs.
post:
operationId: addPatchTargetDevice
tags: [admin]
parameters:
- $ref: '#/components/parameters/PatchId'
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [client_id]
properties:
client_id:
type: string
responses:
'200':
description: Target device added.
/api/v1/admin/patches/{patchId}/target-devices/{clientId}:
delete:
operationId: removePatchTargetDevice
tags: [admin]
parameters:
- $ref: '#/components/parameters/PatchId'
- name: clientId
in: path
required: true
schema:
type: string
responses:
'204':
description: Target device removed.
/api/v1/admin/apps/{appId}/events:
get:
operationId: getPatchEvents
tags: [admin]
parameters:
- $ref: '#/components/parameters/AppId'
responses:
'200':
description: Patch event list.
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
parameters:
AppId:
name: appId
in: path
required: true
schema:
type: string
format: uuid
OrgId:
name: orgId
in: path
required: true
schema:
type: integer
ReleaseId:
name: releaseId
in: path
required: true
schema:
type: integer
PatchId:
name: patchId
in: path
required: true
schema:
type: integer
UserId:
name: userId
in: path
required: true
schema:
type: integer
schemas:
ErrorResponse:
type: object
required: [message]
properties:
message:
type: string
details:
type: [string, 'null']
LoginRequest:
type: object
required: [email, password]
properties:
email:
type: string
format: email
password:
type: string
RegisterRequest:
type: object
required: [email, password, name]
properties:
email:
type: string
format: email
password:
type: string
name:
type: string
AuthTokenResponse:
type: object
additionalProperties: true
properties:
token:
type: string
refresh_token:
type: string
user:
$ref: '#/components/schemas/PrivateUser'
PrivateUser:
type: object
additionalProperties: true
properties:
id:
type: integer
email:
type: string
name:
type: string
PublicUser:
type: object
additionalProperties: true
CreateUserRequest:
type: object
required: [email, password, name]
properties:
email:
type: string
password:
type: string
name:
type: string
Organization:
type: object
additionalProperties: true
properties:
id:
type: integer
name:
type: string
type:
type: string
OrganizationUser:
type: object
additionalProperties: true
App:
type: object
additionalProperties: true
properties:
app_id:
type: string
format: uuid
display_name:
type: string
CreateAppRequest:
type: object
required: [display_name]
properties:
display_name:
type: string
organization_id:
type: integer
Channel:
type: object
additionalProperties: true
properties:
id:
type: integer
name:
type: string
CreateChannelRequest:
type: object
required: [name]
properties:
name:
type: string
Release:
type: object
additionalProperties: true
properties:
id:
type: integer
version:
type: string
flutter_revision:
type: string
CreateReleaseRequest:
type: object
additionalProperties: true
required: [version, flutter_revision]
properties:
version:
type: string
flutter_revision:
type: string
flutter_version:
type: string
platform_statuses:
type: object
additionalProperties: true
UpdateReleaseRequest:
type: object
additionalProperties: true
CreateReleaseArtifactRequest:
type: object
additionalProperties: true
required: [arch, platform, hash, size, storage_key]
properties:
arch:
type: string
platform:
type: string
hash:
type: string
size:
type: integer
storage_key:
type: string
can_sideload:
type: boolean
ReleaseArtifact:
type: object
additionalProperties: true
Patch:
type: object
additionalProperties: true
properties:
id:
type: integer
number:
type: integer
CreatePatchRequest:
type: object
additionalProperties: true
required: [release_id]
properties:
release_id:
type: integer
notes:
type: string
UpdatePatchRequest:
type: object
additionalProperties: true
CreatePatchArtifactRequest:
type: object
additionalProperties: true
required: [arch, platform, hash, size, storage_key]
properties:
arch:
type: string
platform:
type: string
hash:
type: string
size:
type: integer
storage_key:
type: string
hash_signature:
type: string
podfile_lock_hash:
type: string
offline_expires_at:
type: string
format: date-time
PromotePatchRequest:
type: object
required: [patch_id, channel]
properties:
patch_id:
type: integer
channel:
type: string
PatchCheckRequest:
type: object
additionalProperties: true
required: [app_id, channel, release_version, platform, arch]
properties:
app_id:
type: string
format: uuid
channel:
type: string
release_version:
type: string
platform:
type: string
arch:
type: string
current_patch_number:
type: [integer, 'null']
client_id:
type: [string, 'null']
accept_encrypted_patch:
type: boolean
PatchCheckResponse:
type: object
additionalProperties: true
properties:
patch_available:
type: boolean
patch:
type: [object, 'null']
remove_patch:
type: [object, 'null']
rolled_back_patch_numbers:
type: array
items:
type: integer
PatchEncryptionMetadata:
type: object
additionalProperties: true