394 lines
13 KiB
YAML
394 lines
13 KiB
YAML
|
|
openapi: 3.0.3
|
|||
|
|
info:
|
|||
|
|
title: Meet External API
|
|||
|
|
version: 1.0.0
|
|||
|
|
description: |
|
|||
|
|
External API for room management with resource server authentication.
|
|||
|
|
[[description by Oauth 2.0]](https://www.oauth.com/oauth2-servers/the-resource-server/)
|
|||
|
|
|
|||
|
|
#### Authentication Flow
|
|||
|
|
|
|||
|
|
1. Authenticate with the authorization server using your credentials
|
|||
|
|
2. During authentication, request the scopes you need: `lasuite_visio` (mandatory) plus action-specific scopes
|
|||
|
|
3. Receive an access token and a refresh token that includes the requested scopes
|
|||
|
|
4. Use the access token in the `Authorization: Bearer <token>` header for all API requests
|
|||
|
|
5. When the access token expires, use the refresh token to obtain a new access token without re-authenticating
|
|||
|
|
|
|||
|
|
#### Scopes
|
|||
|
|
|
|||
|
|
* `lasuite_visio` - **Mandatory** Base scope required for any API access
|
|||
|
|
* `lasuite_visio:rooms:list` – List rooms accessible to the delegated user.
|
|||
|
|
* `lasuite_visio:rooms:retrieve` – Retrieve details of a specific room.
|
|||
|
|
* `lasuite_visio:rooms:create` – Create new rooms.
|
|||
|
|
* `lasuite_visio:rooms:update` – **Coming soon** Update existing rooms, e.g., add attendees to a room.
|
|||
|
|
* `lasuite_visio:rooms:delete` – **Coming soon** Delete rooms generated by the application.
|
|||
|
|
|
|||
|
|
#### Upcoming Features
|
|||
|
|
|
|||
|
|
* **Add attendees to a room:** You will be able to update a room to include a list of attendees, allowing them to bypass the lobby system automatically.
|
|||
|
|
* **Delete application-generated rooms:** Rooms created via the application can be deleted when no longer needed.
|
|||
|
|
|
|||
|
|
contact:
|
|||
|
|
name: API Support
|
|||
|
|
email: antoine.lebaud@mail.numerique.gouv.fr
|
|||
|
|
|
|||
|
|
servers:
|
|||
|
|
- url: https://visio-sandbox.beta.numerique.gouv.fr/external-api/v1.0
|
|||
|
|
description: Sandbox server
|
|||
|
|
|
|||
|
|
tags:
|
|||
|
|
- name: Rooms
|
|||
|
|
description: Room management operations
|
|||
|
|
|
|||
|
|
paths:
|
|||
|
|
/rooms:
|
|||
|
|
get:
|
|||
|
|
tags:
|
|||
|
|
- Rooms
|
|||
|
|
summary: List rooms
|
|||
|
|
description: |
|
|||
|
|
Returns a list of rooms accessible to the authenticated user.
|
|||
|
|
Only rooms where the delegated user has access will be returned.
|
|||
|
|
operationId: listRooms
|
|||
|
|
security:
|
|||
|
|
- BearerAuth: [rooms:list]
|
|||
|
|
parameters:
|
|||
|
|
- name: page
|
|||
|
|
in: query
|
|||
|
|
description: Page number for pagination
|
|||
|
|
schema:
|
|||
|
|
type: integer
|
|||
|
|
minimum: 1
|
|||
|
|
default: 1
|
|||
|
|
- name: page_size
|
|||
|
|
in: query
|
|||
|
|
description: Number of items per page
|
|||
|
|
schema:
|
|||
|
|
type: integer
|
|||
|
|
minimum: 1
|
|||
|
|
maximum: 100
|
|||
|
|
default: 20
|
|||
|
|
responses:
|
|||
|
|
'200':
|
|||
|
|
description: List of accessible rooms
|
|||
|
|
content:
|
|||
|
|
application/json:
|
|||
|
|
schema:
|
|||
|
|
type: object
|
|||
|
|
properties:
|
|||
|
|
count:
|
|||
|
|
type: integer
|
|||
|
|
description: Total number of rooms
|
|||
|
|
next:
|
|||
|
|
type: string
|
|||
|
|
nullable: true
|
|||
|
|
description: URL to next page
|
|||
|
|
previous:
|
|||
|
|
type: string
|
|||
|
|
nullable: true
|
|||
|
|
description: URL to previous page
|
|||
|
|
results:
|
|||
|
|
type: array
|
|||
|
|
items:
|
|||
|
|
$ref: '#/components/schemas/Room'
|
|||
|
|
examples:
|
|||
|
|
roomList:
|
|||
|
|
summary: Paginated room list
|
|||
|
|
value:
|
|||
|
|
count: 2
|
|||
|
|
next: "https://visio-sandbox.beta.numerique.gouv.fr/external-api/v1.0/rooms?page=2"
|
|||
|
|
previous: null
|
|||
|
|
results:
|
|||
|
|
- id: "7c9e6679-7425-40de-944b-e07fc1f90ae7"
|
|||
|
|
slug: "aae-erez-aaz"
|
|||
|
|
access_level: "trusted"
|
|||
|
|
url: "https://visio-sandbox.beta.numerique.gouv.fr/aae-erez-aaz"
|
|||
|
|
telephony:
|
|||
|
|
enabled: true
|
|||
|
|
pin_code: "123456"
|
|||
|
|
phone_number: "+1-555-0100"
|
|||
|
|
default_country: "US"
|
|||
|
|
'401':
|
|||
|
|
$ref: '#/components/responses/UnauthorizedError'
|
|||
|
|
'403':
|
|||
|
|
$ref: '#/components/responses/ForbiddenError'
|
|||
|
|
|
|||
|
|
post:
|
|||
|
|
tags:
|
|||
|
|
- Rooms
|
|||
|
|
summary: Create a room
|
|||
|
|
description: |
|
|||
|
|
Creates a new room with secure defaults for external API usage.
|
|||
|
|
|
|||
|
|
**Restrictions:**
|
|||
|
|
- Rooms are always created with `trusted` access (no public rooms via API)
|
|||
|
|
- Room access_level can be updated from the webapp interface.
|
|||
|
|
|
|||
|
|
**Defaults:**
|
|||
|
|
- Delegated user is set as owner
|
|||
|
|
- Room slug auto-generated for uniqueness
|
|||
|
|
- Telephony PIN auto-generated when enabled
|
|||
|
|
- Creation tracked with application client_id for auditing
|
|||
|
|
operationId: createRoom
|
|||
|
|
security:
|
|||
|
|
- BearerAuth: [rooms:create]
|
|||
|
|
requestBody:
|
|||
|
|
required: false
|
|||
|
|
content:
|
|||
|
|
application/json:
|
|||
|
|
schema:
|
|||
|
|
$ref: '#/components/schemas/RoomCreate'
|
|||
|
|
examples:
|
|||
|
|
emptyBody:
|
|||
|
|
summary: No parameters (default)
|
|||
|
|
value: {}
|
|||
|
|
responses:
|
|||
|
|
'201':
|
|||
|
|
description: Room created successfully
|
|||
|
|
content:
|
|||
|
|
application/json:
|
|||
|
|
schema:
|
|||
|
|
$ref: '#/components/schemas/Room'
|
|||
|
|
'401':
|
|||
|
|
$ref: '#/components/responses/UnauthorizedError'
|
|||
|
|
'403':
|
|||
|
|
$ref: '#/components/responses/ForbiddenError'
|
|||
|
|
|
|||
|
|
/rooms/{id}:
|
|||
|
|
get:
|
|||
|
|
tags:
|
|||
|
|
- Rooms
|
|||
|
|
summary: Retrieve a room
|
|||
|
|
description: Get detailed information about a specific room by its ID
|
|||
|
|
operationId: retrieveRoom
|
|||
|
|
security:
|
|||
|
|
- BearerAuth: [rooms:retrieve]
|
|||
|
|
parameters:
|
|||
|
|
- name: id
|
|||
|
|
in: path
|
|||
|
|
required: true
|
|||
|
|
description: Room UUID
|
|||
|
|
schema:
|
|||
|
|
type: string
|
|||
|
|
format: uuid
|
|||
|
|
responses:
|
|||
|
|
'200':
|
|||
|
|
description: Room details
|
|||
|
|
content:
|
|||
|
|
application/json:
|
|||
|
|
schema:
|
|||
|
|
$ref: '#/components/schemas/Room'
|
|||
|
|
examples:
|
|||
|
|
room:
|
|||
|
|
summary: Room details
|
|||
|
|
value:
|
|||
|
|
id: "7c9e6679-7425-40de-944b-e07fc1f90ae7"
|
|||
|
|
slug: "aae-erez-aaz"
|
|||
|
|
access_level: "trusted"
|
|||
|
|
url: "https://visio-sandbox.beta.numerique.gouv.fr/aae-erez-aaz"
|
|||
|
|
telephony:
|
|||
|
|
enabled: true
|
|||
|
|
pin_code: "123456"
|
|||
|
|
phone_number: "+1-555-0100"
|
|||
|
|
default_country: "US"
|
|||
|
|
'401':
|
|||
|
|
$ref: '#/components/responses/UnauthorizedError'
|
|||
|
|
'403':
|
|||
|
|
$ref: '#/components/responses/ForbiddenError'
|
|||
|
|
'404':
|
|||
|
|
$ref: '#/components/responses/RoomNotFoundError'
|
|||
|
|
|
|||
|
|
components:
|
|||
|
|
securitySchemes:
|
|||
|
|
BearerAuth:
|
|||
|
|
type: http
|
|||
|
|
scheme: bearer
|
|||
|
|
bearerFormat: JWT
|
|||
|
|
description: |
|
|||
|
|
JWT token obtained from the `/application/token` endpoint.
|
|||
|
|
Include in requests as: `Authorization: Bearer <token>`
|
|||
|
|
|
|||
|
|
schemas:
|
|||
|
|
TokenRequest:
|
|||
|
|
type: object
|
|||
|
|
required:
|
|||
|
|
- client_id
|
|||
|
|
- client_secret
|
|||
|
|
- grant_type
|
|||
|
|
- scope
|
|||
|
|
properties:
|
|||
|
|
client_id:
|
|||
|
|
type: string
|
|||
|
|
description: Application client identifier
|
|||
|
|
example: "550e8400-e29b-41d4-a716-446655440000"
|
|||
|
|
client_secret:
|
|||
|
|
type: string
|
|||
|
|
format: password
|
|||
|
|
writeOnly: true
|
|||
|
|
description: Application secret key
|
|||
|
|
example: "1234567890abcdefghijklmnopqrstuvwxyz"
|
|||
|
|
grant_type:
|
|||
|
|
type: string
|
|||
|
|
enum:
|
|||
|
|
- client_credentials
|
|||
|
|
description: OAuth2 grant type (must be 'client_credentials')
|
|||
|
|
example: "client_credentials"
|
|||
|
|
scope:
|
|||
|
|
type: string
|
|||
|
|
format: email
|
|||
|
|
description: |
|
|||
|
|
Email address of the user to delegate.
|
|||
|
|
The application will act on behalf of this user.
|
|||
|
|
Note: This parameter is named 'scope' to align with OAuth2 conventions,
|
|||
|
|
but accepts an email address to identify the user. This design allows
|
|||
|
|
for future extensibility.
|
|||
|
|
example: "user@example.com"
|
|||
|
|
|
|||
|
|
TokenResponse:
|
|||
|
|
type: object
|
|||
|
|
properties:
|
|||
|
|
access_token:
|
|||
|
|
type: string
|
|||
|
|
description: JWT access token
|
|||
|
|
example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJtZWV0LWFwaSIsImF1ZCI6Im1lZXQtY2xpZW50cyIsImlhdCI6MTcwOTQ5MTIwMCwiZXhwIjoxNzA5NDk0ODAwLCJjbGllbnRfaWQiOiI1NTBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMDAiLCJzY29wZSI6InJvb21zOmxpc3Qgcm9vbXM6cmV0cmlldmUgcm9vbXM6Y3JlYXRlIiwidXNlcl9pZCI6IjdiOGQ5YzQwLTNhMmItNGVkZi04NzFjLTJmM2Q0ZTVmNmE3YiIsImRlbGVnYXRlZCI6dHJ1ZX0.signature"
|
|||
|
|
token_type:
|
|||
|
|
type: string
|
|||
|
|
description: Token type (always 'Bearer')
|
|||
|
|
example: "Bearer"
|
|||
|
|
expires_in:
|
|||
|
|
type: integer
|
|||
|
|
description: Token lifetime in seconds
|
|||
|
|
example: 3600
|
|||
|
|
scope:
|
|||
|
|
type: string
|
|||
|
|
description: Space-separated list of granted permission scopes
|
|||
|
|
example: "rooms:list rooms:retrieve rooms:create"
|
|||
|
|
|
|||
|
|
RoomCreate:
|
|||
|
|
type: object
|
|||
|
|
description: Empty object - all room properties are auto-generated
|
|||
|
|
properties: {}
|
|||
|
|
|
|||
|
|
Room:
|
|||
|
|
type: object
|
|||
|
|
properties:
|
|||
|
|
id:
|
|||
|
|
type: string
|
|||
|
|
format: uuid
|
|||
|
|
readOnly: true
|
|||
|
|
description: Unique room identifier
|
|||
|
|
example: "7c9e6679-7425-40de-944b-e07fc1f90ae7"
|
|||
|
|
slug:
|
|||
|
|
type: string
|
|||
|
|
readOnly: true
|
|||
|
|
description: URL-friendly room identifier (auto-generated)
|
|||
|
|
example: "aze-eere-zer"
|
|||
|
|
access_level:
|
|||
|
|
type: string
|
|||
|
|
readOnly: true
|
|||
|
|
description: Room access level (always 'trusted' for API-created rooms)
|
|||
|
|
example: "trusted"
|
|||
|
|
url:
|
|||
|
|
type: string
|
|||
|
|
format: uri
|
|||
|
|
readOnly: true
|
|||
|
|
description: Full URL to access the room
|
|||
|
|
example: "https://visio-sandbox.beta.numerique.gouv.fr/aze-eere-zer"
|
|||
|
|
telephony:
|
|||
|
|
type: object
|
|||
|
|
readOnly: true
|
|||
|
|
description: Telephony dial-in information (if enabled)
|
|||
|
|
properties:
|
|||
|
|
enabled:
|
|||
|
|
type: boolean
|
|||
|
|
description: Whether telephony is available
|
|||
|
|
example: true
|
|||
|
|
pin_code:
|
|||
|
|
type: string
|
|||
|
|
description: PIN code for dial-in access
|
|||
|
|
example: "123456"
|
|||
|
|
phone_number:
|
|||
|
|
type: string
|
|||
|
|
description: Phone number to dial
|
|||
|
|
example: "+1-555-0100"
|
|||
|
|
default_country:
|
|||
|
|
type: string
|
|||
|
|
description: Default country code
|
|||
|
|
example: "US"
|
|||
|
|
|
|||
|
|
OAuthError:
|
|||
|
|
type: object
|
|||
|
|
description: OAuth2-compliant error response
|
|||
|
|
properties:
|
|||
|
|
error:
|
|||
|
|
type: string
|
|||
|
|
description: Human-readable error description
|
|||
|
|
example: "Invalid credentials"
|
|||
|
|
|
|||
|
|
Error:
|
|||
|
|
type: object
|
|||
|
|
properties:
|
|||
|
|
detail:
|
|||
|
|
type: string
|
|||
|
|
description: Error message
|
|||
|
|
example: "Invalid token."
|
|||
|
|
|
|||
|
|
ValidationError:
|
|||
|
|
type: object
|
|||
|
|
properties:
|
|||
|
|
field_name:
|
|||
|
|
type: array
|
|||
|
|
items:
|
|||
|
|
type: string
|
|||
|
|
description: List of validation errors for this field
|
|||
|
|
example: ["This field is required."]
|
|||
|
|
|
|||
|
|
responses:
|
|||
|
|
UnauthorizedError:
|
|||
|
|
description: The access token is expired, revoked, malformed, or invalid for other reasons. The client can obtain a new access token and try again.
|
|||
|
|
content:
|
|||
|
|
application/json:
|
|||
|
|
schema:
|
|||
|
|
$ref: '#/components/schemas/Error'
|
|||
|
|
examples:
|
|||
|
|
invalidToken:
|
|||
|
|
summary: Invalid token
|
|||
|
|
value:
|
|||
|
|
error: "Invalid token."
|
|||
|
|
|
|||
|
|
ForbiddenError:
|
|||
|
|
description: Insufficient scope for this operation
|
|||
|
|
content:
|
|||
|
|
application/json:
|
|||
|
|
schema:
|
|||
|
|
$ref: '#/components/schemas/Error'
|
|||
|
|
examples:
|
|||
|
|
insufficientScope:
|
|||
|
|
summary: Missing required scope
|
|||
|
|
value:
|
|||
|
|
detail: "Insufficient permissions. Required scope: 'rooms:xxxx'"
|
|||
|
|
|
|||
|
|
RoomNotFoundError:
|
|||
|
|
description: Room not found
|
|||
|
|
content:
|
|||
|
|
application/json:
|
|||
|
|
schema:
|
|||
|
|
$ref: '#/components/schemas/Error'
|
|||
|
|
examples:
|
|||
|
|
roomNotFound:
|
|||
|
|
summary: Room does not exist
|
|||
|
|
value:
|
|||
|
|
detail: "Not found."
|
|||
|
|
|
|||
|
|
BadRequestError:
|
|||
|
|
description: Invalid request data
|
|||
|
|
content:
|
|||
|
|
application/json:
|
|||
|
|
schema:
|
|||
|
|
$ref: '#/components/schemas/ValidationError'
|
|||
|
|
examples:
|
|||
|
|
validationError:
|
|||
|
|
summary: Field validation failed
|
|||
|
|
value:
|
|||
|
|
scope: ["Invalid email address."]
|