swagger.yml 45.5 KB
Newer Older
1
2
3
4
5
6
7
8
# Undocumented endpoints:
#  /api/v1/settings
#  /api/v1/activity
#  /api/v1/playlist-tracks
#  /api/v1/search
#  /api/v1/radios
#  /api/v1/history

9
openapi: "3.0.2"
10
info:
Eliot Berriot's avatar
Eliot Berriot committed
11
12
13
14
15
16
  description: |
    Interactive documentation for [Funkwhale](https://funkwhale.audio) API.

    The API is **not** freezed yet, but we will document breaking changes in our changelog,
    and try to avoid those as much as possible.

Eliot Berriot's avatar
Eliot Berriot committed
17
18
19
20
21
22
23
24
25
26
27
    Usage
    -----

    Click on an endpoint name to inspect its properties, parameters and responses.

    Use the "Try it out" button to send a real world payload to the endpoint and inspect
    the corresponding response.

    Authentication
    --------------

Agate's avatar
Agate committed
28
    To authenticate, use OAuth. You can register your own app using the `/apps` endpoint and proceed to the OAuth flow afterwards.
Eliot Berriot's avatar
Eliot Berriot committed
29

Agate's avatar
Agate committed
30
    You can use our demo server at `https://demo.funkwhale.audio` for testing purposes.
Eliot Berriot's avatar
Eliot Berriot committed
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
    Rate limiting
    -------------

    Depending on server configuration, pods running Funkwhale 0.20 and higher may rate-limit incoming
    requests to prevent abuse and improve the stability of service. Requests that are dropped because of rate-limiting
    receive a 429 HTTP response.

    The limits themselves vary depending on:

    - The client: anonymous requests are subject to lower limits than authenticated requests
    - The operation being performed: Write and delete operations, as performed with DELETE, POST, PUT and PATCH HTTP methods are subject to lower limits

    Those conditions are used to determine the scope of the request, which in turns determine the limit that is applied.
    For instance, authenticated POST requests are bound to the `authenticated-create` scope, with a default limit of
    1000 requests/hour, but anonymous POST requests are bound to the `anonymous-create` scope, with a lower limit of 1000 requests/day.

    A full list of scopes with their corresponding description, and the current usage data for the client performing the request
    is available via the `/api/v1/rate-limit` endpoint.

    Additionally, we include HTTP headers on all API response to ensure API clients can understand:

    - what scope was bound to a given request
    - what is the corresponding limit
    - how much similar requests can be sent before being limited
    - and how much time they should wait if they have been limited

    <table>
      <caption>Rate limiting headers</caption>
      <thead>
        <th>Header</th>
        <th>Example value</th>
        <th>Description value</th>
      </thead>
      <tbody>
        <tr>
          <td><code>X-RateLimit-Limit</code></td>
          <td>50</td>
          <td>The number of allowed requests whithin a given period</td>
        </tr>
        <tr>
          <td><code>X-RateLimit-Duration</code></td>
          <td>3600</td>
          <td>The time window, in seconds, during which those requests are accounted for.</td>
        </tr>
        <tr>
          <td><code>X-RateLimit-Scope</code></td>
          <td>login</td>
          <td>The name of the scope as computed for the request</td>
        </tr>
        <tr>
          <td><code>X-RateLimit-Remaining</code></td>
          <td>42</td>
          <td>How many requests can be sent with the same scope before the limit applies</td>
        </tr>
        <tr>
          <td><code>Retry-After</code> (if <code>X-RateLimit-Remaining</code> is 0)</td>
          <td>3543</td>
          <td>How many seconds to wait before a retry</td>
        </tr>
        <tr>
          <td><code>X-RateLimit-Reset</code></td>
          <td>1568126089</td>
          <td>A timestamp indicating when <code>X-RateLimit-Remaining</code> will return to its higher possible value</td>
        </tr>
        <tr>
          <td><code>X-RateLimit-ResetSeconds</code></td>
          <td>3599</td>
          <td>How many seconds to wait before <code>X-RateLimit-Remaining</code> returns to its higher possible value</td>
        </tr>
      </tbody>
    </table>


Eliot Berriot's avatar
Eliot Berriot committed
105
106
107
    Resources
    ---------

Eliot Berriot's avatar
Eliot Berriot committed
108
109
110
    For more targeted guides regarding API usage, and especially authentication, please
    refer to [https://docs.funkwhale.audio/api.html](https://docs.funkwhale.audio/api.html)

111
112
113
114
  version: "1.0.0"
  title: "Funkwhale API"

servers:
115
  - url: https://demo.funkwhale.audio
116
    description: Demo server
117
118
  - url: https://open.audio
    description: Real server with real content
119
  - url: https://{domain}
120
121
122
123
124
125
126
127
128
129
    description: Custom server
    variables:
      domain:
        default: yourdomain
        description: Your Funkwhale Domain
      protocol:
        enum:
          - 'http'
          - 'https'
        default: 'https'
130
131
132

components:
  securitySchemes:
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
    oauth2:
      type: oauth2
      description: This API uses OAuth 2 with the Authorization Code flow. You can register an app using the /oauth/apps/ endpoint.
      flows:
        authorizationCode:
          # Swagger doesn't support relative URLs yet (cf https://github.com/swagger-api/swagger-ui/pull/5244)
          authorizationUrl: /authorize
          tokenUrl: /api/v1/oauth/token/
          refreshUrl: /api/v1/oauth/token/
          scopes:
            "read": "Read-only access to all user data"
            "write": "Write-only access on all user data"
            "read:profile": "Read-only access to profile data"
            "read:libraries": "Read-only access to library and uploads"
            "read:playlists": "Read-only access to playlists"
            "read:listenings": "Read-only access to listening history"
            "read:favorites": "Read-only access to favorites"
            "read:radios": "Read-only access to radios"
            "read:edits": "Read-only access to edits"
            "read:notifications": "Read-only access to notifications"
            "read:follows": "Read-only to follows"
            "read:filters": "Read-only to to content filters"
            "write:profile": "Write-only access to profile data"
            "write:libraries": "Write-only access to libraries"
            "write:playlists": "Write-only access to playlists"
            "write:follows": "Write-only access to follows"
            "write:favorites": "Write-only access to favorits"
            "write:notifications": "Write-only access to notifications"
            "write:radios": "Write-only access to radios"
            "write:edits": "Write-only access to edits"
            "write:filters": "Write-only access to content-filters"
            "write:listenings": "Write-only access to listening history"
165
166
167
168
169
170
171
172
    jwt:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: "You can get a token by using the /token endpoint"

security:
  - jwt: []
173
  - oauth2: []
174

175
176
tags:
  - name: Auth and security
177
    description: Login, logout, rate-limit and authorization endpoints
178
179
180
181
182
183
  - name: Library and metadata
    description: Information and metadata about musical and audio entities (albums, tracks, artists, etc.)
  - name: Uploads and audio content
    description: Manipulation and uploading of audio files
    externalDocs:
      url: https://docs.funkwhale.audio/users/managing.html
Agate's avatar
Agate committed
184
185
186
187
  - name: Channels and subscriptions
    description: Channel management and subscription
    externalDocs:
      url: https://docs.funkwhale.audio/users/upload.html#using-a-channel
Eliot Berriot's avatar
Eliot Berriot committed
188
189
  - name: Content curation
    description: Favorites, playlists, radios
Eliot Berriot's avatar
Eliot Berriot committed
190
191
  - name: Other
    description: Other endpoints that don't fit in the categories above
192

193
paths:
194
195
196
  /api/v1/oauth/apps/:
    post:
      tags:
197
        - "Auth and security"
198
199
200
201
202
203
204
205
206
      description:
        Register an OAuth application
      security: []
      responses:
        201:
          content:
            application/json:
              schema:
                allOf:
Agate's avatar
Agate committed
207
208
                  - $ref: "./api/definitions.yml#/OAuthApplication"
                  - $ref: "./api/definitions.yml#/OAuthApplicationCreation"
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                name:
                  type: "string"
                  example: "My Awesome Funkwhale Client"
                  summary: "A human readable name for your app"
                redirect_uris:
                  type: "string"
                  example: "https://myapp/oauth2/funkwhale"
                  summary: "A list of redirect uris, separated by spaces"
                scopes:
                  type: "string"
                  summary: "A list of scopes requested by your app, separated by spaces"
                  example: "read write:playlists write:favorites"
  /api/v1/token/:
229
230
    post:
      tags:
231
        - "Auth and security"
232
      summary: Get an API token
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
      description:
        Obtain a JWT token you can use for authenticating your next requests.
      security: []
      responses:
        '200':
          description: Successfull auth
        '400':
          description: Invalid credentials
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                username:
                  type: "string"
                  example: "demo"
                password:
                  type: "string"
                  example: "demo"

255
  /api/v1/auth/registration/:
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
    post:
      summary: Create an account
      description: |
        Register a new account on this instance. An invitation code will be required
        if sign up is disabled.
      tags:
        - "Auth and security"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                username:
                  type: "string"
                  example: "alice"
                email:
                  type: "string"
                  format: "email"
                invitation:
                  type: "string"
                  example: "INVITECODE"
                  required: false
                  description: An invitation code, required if signups are closed on the instance.
                password1:
                  type: "string"
                  example: "passw0rd"
                password2:
                  type: "string"
                  description: Must be identical to password1
                  example: "passw0rd"
      responses:
        201:
          $ref: "#/responses/201"
291
  /api/v1/auth/password/reset/:
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
    post:
      summary: Request a password reset
      description: |
        Request a password reset. An email with reset instructions will be sent to the provided email,
        if it's associated with a user account.
      tags:
        - "Auth and security"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                email:
                  type: "string"
                  format: "email"
      responses:
        200:
          $ref: "#/responses/200"
312
  /api/v1/users/users/me/:
313
314
315
316
317
318
319
320
321
322
323
324
    get:
      summary: Retrive profile information
      description: |
        Retrieve profile informations of the current user
      tags:
        - "Auth and security"

      responses:
        200:
          content:
            application/json:
              schema:
Agate's avatar
Agate committed
325
                $ref: "./api/definitions.yml#/Me"
326

327
328
329
330
331
332
333
334
335
336
337
  /api/v1/rate-limit/:
    get:
      summary: Retrive rate-limit information and current usage status
      tags:
        - "Auth and security"

      responses:
        200:
          content:
            application/json:
              schema:
Agate's avatar
Agate committed
338
                $ref: "./api/definitions.yml#/RateLimitStatus"
339

340
  /api/v1/artists/:
341
    get:
Eliot Berriot's avatar
Eliot Berriot committed
342
      summary: List artists
343
      tags:
344
        - "Library and metadata"
345
346
347
      security:
        - oauth2:
          - "read:libraries"
348
      parameters:
Agate's avatar
Agate committed
349

Agate's avatar
Agate committed
350
        - $ref: "./api/parameters.yml#/Search"
Eliot Berriot's avatar
Eliot Berriot committed
351
        - allOf:
Agate's avatar
Agate committed
352
            - $ref: "./api/parameters.yml#/Ordering"
Eliot Berriot's avatar
Eliot Berriot committed
353
354
355
356
357
358
359
360
361
            - default: "-creation_date"
              schema:
                required: false
                type: "string"
                example: "creation_date"
                enum:
                  - creation_date
                  - id
                  - name
Agate's avatar
Agate committed
362
363
364
365
        - $ref: "./api/parameters.yml#/Playable"
        - $ref: "./api/parameters.yml#/PageNumber"
        - $ref: "./api/parameters.yml#/PageSize"
        - $ref: "./api/parameters.yml#/Scope"
Eliot Berriot's avatar
Eliot Berriot committed
366
367
368
369
370
371
372

      responses:
        200:
          content:
            application/json:
              schema:
                allOf:
Agate's avatar
Agate committed
373
                  - $ref: "./api/definitions.yml#/ResultPage"
Eliot Berriot's avatar
Eliot Berriot committed
374
375
376
377
378
                  - type: "object"
                    properties:
                      results:
                        type: "array"
                        items:
Agate's avatar
Agate committed
379
                          $ref: "./api/definitions.yml#/Artist"
380
  /api/v1/artists/{id}/:
Eliot Berriot's avatar
Eliot Berriot committed
381
382
383
    get:
      summary: Retrieve a single artist
      parameters:
Agate's avatar
Agate committed
384
385
        - $ref: "./api/parameters.yml#/ObjectId"
        - $ref: "./api/parameters.yml#/Refresh"
386
387
388
      security:
        - oauth2:
          - "read:libraries"
Eliot Berriot's avatar
Eliot Berriot committed
389
      tags:
390
        - "Library and metadata"
Eliot Berriot's avatar
Eliot Berriot committed
391
392
393
394
395
      responses:
        200:
          content:
            application/json:
              schema:
Agate's avatar
Agate committed
396
                $ref: "./api/definitions.yml#/Artist"
Eliot Berriot's avatar
Eliot Berriot committed
397
398
399
400
        404:
          content:
            application/json:
              schema:
Agate's avatar
Agate committed
401
                $ref: "./api/definitions.yml#/ResourceNotFound"
402
  /api/v1/artists/{id}/libraries/:
Eliot Berriot's avatar
Eliot Berriot committed
403
404
    get:
      summary: List available user libraries containing work from this artist
405
406
407
      security:
        - oauth2:
          - "read:libraries"
Eliot Berriot's avatar
Eliot Berriot committed
408
      parameters:
Agate's avatar
Agate committed
409
410
411
        - $ref: "./api/parameters.yml#/ObjectId"
        - $ref: "./api/parameters.yml#/PageNumber"
        - $ref: "./api/parameters.yml#/PageSize"
Eliot Berriot's avatar
Eliot Berriot committed
412
413

      tags:
414
        - "Library and metadata"
Eliot Berriot's avatar
Eliot Berriot committed
415
416
417
418
419
      responses:
        200:
          content:
            application/json:
              schema:
Agate's avatar
Agate committed
420
                $ref: "./api/definitions.yml#/LibraryPage"
Eliot Berriot's avatar
Eliot Berriot committed
421
422
423
424
        404:
          content:
            application/json:
              schema:
Agate's avatar
Agate committed
425
                $ref: "./api/definitions.yml#/ResourceNotFound"
Eliot Berriot's avatar
Eliot Berriot committed
426

427
  /api/v1/albums/:
Eliot Berriot's avatar
Eliot Berriot committed
428
429
430
    get:
      summary: List albums
      tags:
431
        - "Library and metadata"
432
433
434
435

      security:
        - oauth2:
          - "read:libraries"
Eliot Berriot's avatar
Eliot Berriot committed
436
      parameters:
Agate's avatar
Agate committed
437

Agate's avatar
Agate committed
438
        - $ref: "./api/parameters.yml#/Search"
Eliot Berriot's avatar
Eliot Berriot committed
439
440
441
442
443
444
445
446
447
        - name: "artist"
          in: "query"
          default: null
          description: "Only include albums by the requested artist"
          schema:
            required: false
            type: "integer"
            format: "int64"
        - allOf:
Agate's avatar
Agate committed
448
            - $ref: "./api/parameters.yml#/Ordering"
Eliot Berriot's avatar
Eliot Berriot committed
449
450
451
452
453
454
455
456
457
            - default: "-creation_date"
              schema:
                required: false
                type: "string"
                example: "creation_date"
                enum:
                  - creation_date
                  - release_date
                  - title
Agate's avatar
Agate committed
458
459
460
461
        - $ref: "./api/parameters.yml#/Playable"
        - $ref: "./api/parameters.yml#/PageNumber"
        - $ref: "./api/parameters.yml#/PageSize"
        - $ref: "./api/parameters.yml#/Scope"
Eliot Berriot's avatar
Eliot Berriot committed
462
463
464
465
466
467
468

      responses:
        200:
          content:
            application/json:
              schema:
                allOf:
Agate's avatar
Agate committed
469
                  - $ref: "./api/definitions.yml#/ResultPage"
Eliot Berriot's avatar
Eliot Berriot committed
470
471
472
473
474
                  - type: "object"
                    properties:
                      results:
                        type: "array"
                        items:
Agate's avatar
Agate committed
475
                          $ref: "./api/definitions.yml#/Album"
476
  /api/v1/albums/{id}/:
Eliot Berriot's avatar
Eliot Berriot committed
477
478
479
    get:
      summary: Retrieve a single album
      parameters:
Agate's avatar
Agate committed
480
481
        - $ref: "./api/parameters.yml#/ObjectId"
        - $ref: "./api/parameters.yml#/Refresh"
Eliot Berriot's avatar
Eliot Berriot committed
482

483
484
485
      security:
        - oauth2:
          - "read:libraries"
Eliot Berriot's avatar
Eliot Berriot committed
486
      tags:
487
        - "Library and metadata"
Eliot Berriot's avatar
Eliot Berriot committed
488
489
490
491
492
      responses:
        200:
          content:
            application/json:
              schema:
Agate's avatar
Agate committed
493
                $ref: "./api/definitions.yml#/Album"
Eliot Berriot's avatar
Eliot Berriot committed
494
495
496
497
        404:
          content:
            application/json:
              schema:
Agate's avatar
Agate committed
498
                $ref: "./api/definitions.yml#/ResourceNotFound"
Eliot Berriot's avatar
Eliot Berriot committed
499

500
  /api/v1/albums/{id}/libraries/:
Eliot Berriot's avatar
Eliot Berriot committed
501
502
503
    get:
      summary: List available user libraries containing tracks from this album
      parameters:
Agate's avatar
Agate committed
504
505
506
        - $ref: "./api/parameters.yml#/ObjectId"
        - $ref: "./api/parameters.yml#/PageNumber"
        - $ref: "./api/parameters.yml#/PageSize"
Eliot Berriot's avatar
Eliot Berriot committed
507

508
509
510
      security:
        - oauth2:
          - "read:libraries"
Eliot Berriot's avatar
Eliot Berriot committed
511
      tags:
512
        - "Library and metadata"
Eliot Berriot's avatar
Eliot Berriot committed
513
514
515
516
517
      responses:
        200:
          content:
            application/json:
              schema:
Agate's avatar
Agate committed
518
                $ref: "./api/definitions.yml#/LibraryPage"
Eliot Berriot's avatar
Eliot Berriot committed
519
520
521
522
        404:
          content:
            application/json:
              schema:
Agate's avatar
Agate committed
523
                $ref: "./api/definitions.yml#/ResourceNotFound"
Eliot Berriot's avatar
Eliot Berriot committed
524

525
  /api/v1/tracks/:
Eliot Berriot's avatar
Eliot Berriot committed
526
527
528
    get:
      summary: List tracks
      tags:
529
        - "Library and metadata"
530
531
532
533

      security:
        - oauth2:
          - "read:libraries"
Eliot Berriot's avatar
Eliot Berriot committed
534
      parameters:
Agate's avatar
Agate committed
535

Agate's avatar
Agate committed
536
        - $ref: "./api/parameters.yml#/Search"
Eliot Berriot's avatar
Eliot Berriot committed
537
538
539
540
541
542
543
544
        - name: "artist"
          in: "query"
          default: null
          description: "Only include tracks by the requested artist"
          schema:
            required: false
            type: "integer"
            format: "int64"
Eliot Berriot's avatar
Eliot Berriot committed
545
546
547
548
549
550
551
        - name: "favorites"
          in: "query"
          default: null
          description: "filter/exclude tracks favorited by the current user"
          schema:
            required: false
            type: "boolean"
Eliot Berriot's avatar
Eliot Berriot committed
552
553
554
555
556
557
558
559
560
        - name: "album"
          in: "query"
          default: null
          description: "Only include tracks from the requested album"
          schema:
            required: false
            type: "integer"
            format: "int64"
        - name: "license"
561
          in: "query"
Eliot Berriot's avatar
Eliot Berriot committed
562
563
          description: "Only include tracks with the given license"
          default: null
564
          schema:
Eliot Berriot's avatar
Eliot Berriot committed
565
            example: "cc-by-sa-4.0"
566
            required: false
Eliot Berriot's avatar
Eliot Berriot committed
567
568
            type: "string"
        - allOf:
Agate's avatar
Agate committed
569
            - $ref: "./api/parameters.yml#/Ordering"
Eliot Berriot's avatar
Eliot Berriot committed
570
571
572
573
574
575
576
577
578
            - default: "-creation_date"
              schema:
                required: false
                type: "string"
                example: "creation_date"
                enum:
                  - creation_date
                  - release_date
                  - title
Agate's avatar
Agate committed
579
580
581
582
        - $ref: "./api/parameters.yml#/Playable"
        - $ref: "./api/parameters.yml#/PageNumber"
        - $ref: "./api/parameters.yml#/PageSize"
        - $ref: "./api/parameters.yml#/Scope"
Eliot Berriot's avatar
Eliot Berriot committed
583

584
585
586
587
588
      responses:
        200:
          content:
            application/json:
              schema:
Eliot Berriot's avatar
Eliot Berriot committed
589
                allOf:
Agate's avatar
Agate committed
590
                  - $ref: "./api/definitions.yml#/ResultPage"
Eliot Berriot's avatar
Eliot Berriot committed
591
592
593
594
595
                  - type: "object"
                    properties:
                      results:
                        type: "array"
                        items:
Agate's avatar
Agate committed
596
                          $ref: "./api/definitions.yml#/Track"
597
  /api/v1/tracks/{id}/:
Eliot Berriot's avatar
Eliot Berriot committed
598
599
    get:
      parameters:
Agate's avatar
Agate committed
600
601
        - $ref: "./api/parameters.yml#/ObjectId"
        - $ref: "./api/parameters.yml#/Refresh"
602
      summary: Retrieve a single track
Eliot Berriot's avatar
Eliot Berriot committed
603

604
605
606
      security:
        - oauth2:
          - "read:libraries"
Eliot Berriot's avatar
Eliot Berriot committed
607
      tags:
608
        - "Library and metadata"
Eliot Berriot's avatar
Eliot Berriot committed
609
610
611
612
613
      responses:
        200:
          content:
            application/json:
              schema:
Agate's avatar
Agate committed
614
                $ref: "./api/definitions.yml#/Track"
Eliot Berriot's avatar
Eliot Berriot committed
615
616
617
618
        404:
          content:
            application/json:
              schema:
Agate's avatar
Agate committed
619
                $ref: "./api/definitions.yml#/ResourceNotFound"
Eliot Berriot's avatar
Eliot Berriot committed
620

621
  /api/v1/tracks/{id}/libraries/:
Eliot Berriot's avatar
Eliot Berriot committed
622
623
624
    get:
      summary: List available user libraries containing given track
      parameters:
Agate's avatar
Agate committed
625
626
627
        - $ref: "./api/parameters.yml#/ObjectId"
        - $ref: "./api/parameters.yml#/PageNumber"
        - $ref: "./api/parameters.yml#/PageSize"
628
629
630
      security:
        - oauth2:
          - "read:libraries"
Eliot Berriot's avatar
Eliot Berriot committed
631
      tags:
632
        - "Library and metadata"
Eliot Berriot's avatar
Eliot Berriot committed
633
634
635
636
637
      responses:
        200:
          content:
            application/json:
              schema:
Agate's avatar
Agate committed
638
                $ref: "./api/definitions.yml#/LibraryPage"
Eliot Berriot's avatar
Eliot Berriot committed
639
640
641
642
        404:
          content:
            application/json:
              schema:
Agate's avatar
Agate committed
643
                $ref: "./api/definitions.yml#/ResourceNotFound"
644
  /api/v1/listen/{uuid}/:
Eliot Berriot's avatar
Eliot Berriot committed
645
646
647
648
649
    get:
      summary: Download the audio file matching the given track uuid
      description: |
        Given a track uuid (and not ID), return the first found audio file
        accessible by the user making the request.
Eliot Berriot's avatar
Eliot Berriot committed
650

Eliot Berriot's avatar
Eliot Berriot committed
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
        In case of a remote upload, this endpoint will fetch the audio file from the remote
        and cache it before sending the response.

      parameters:
        - name: uuid
          in: path
          required: true
          description: Track uuid
          schema:
            type: "string"
            format: "uuid"
        - name: to
          in: query
          required: false
          description: |
            If specified, the endpoint will return a transcoded version of the original
            audio file.

            Since transcoding happens on the fly, it can significantly increase response time,
            and it's recommended to request transcoding only for files that are not playable
            by the client.

            This endpoint support bytess-range requests.
          schema:
Agate's avatar
Agate committed
675
            $ref: "./api/properties.yml#/transcode_options"
Eliot Berriot's avatar
Eliot Berriot committed
676
677
678
679
680
681
682
683
684
685
686
687
        - name: upload
          in: query
          required: false
          summary: An upload uuid
          description: |
            If specified, will return the audio for the given upload uuid.

            This is useful for tracks that have multiple uploads available.

          schema:
            type: string
            format: uuid
Agate's avatar
Agate committed
688
689
690
691
692
693
694
695
696
697
        - name: token
          in: query
          required: false
          description: |
            A listen token as returned by /users/me

            This offers an alternative authentication method for situations where HTTP headers
            can't be modified to include a Bearer token.
          schema:
            type: string
Eliot Berriot's avatar
Eliot Berriot committed
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712

      tags:
        - "Library and metadata"
      responses:
        200:
          content:
            '*/*':
              description: "Audio file, as binary data"
              schema:
                type: string
                format: binary
        404:
          content:
            application/json:
              schema:
Agate's avatar
Agate committed
713
                $ref: "./api/definitions.yml#/ResourceNotFound"
Eliot Berriot's avatar
Eliot Berriot committed
714

715
  /api/v1/licenses/:
Eliot Berriot's avatar
Eliot Berriot committed
716
717
    get:
      summary: List licenses
718
719
720
      security:
        - oauth2:
          - "read:libraries"
Eliot Berriot's avatar
Eliot Berriot committed
721
      tags:
722
        - "Library and metadata"
Eliot Berriot's avatar
Eliot Berriot committed
723
      parameters:
Agate's avatar
Agate committed
724
725
        - $ref: "./api/parameters.yml#/PageNumber"
        - $ref: "./api/parameters.yml#/PageSize"
Eliot Berriot's avatar
Eliot Berriot committed
726
727
728
729
730
731
      responses:
        200:
          content:
            application/json:
              schema:
                allOf:
Agate's avatar
Agate committed
732
                  - $ref: "./api/definitions.yml#/ResultPage"
Eliot Berriot's avatar
Eliot Berriot committed
733
734
735
736
737
                  - type: "object"
                    properties:
                      results:
                        type: "array"
                        items:
Agate's avatar
Agate committed
738
                          $ref: "./api/definitions.yml#/License"
Eliot Berriot's avatar
Eliot Berriot committed
739

740
  /api/v1/licenses/{code}/:
Eliot Berriot's avatar
Eliot Berriot committed
741
742
    get:
      summary: Retrieve a single license
743
744
745
      security:
        - oauth2:
          - "read:libraries"
Eliot Berriot's avatar
Eliot Berriot committed
746
747
748
749
750
751
752
753
754
755
      parameters:
        - name: code
          in: path
          description: License code
          required: true
          schema:
            type: string
            example: cc0-1.0

      tags:
756
        - "Library and metadata"
Eliot Berriot's avatar
Eliot Berriot committed
757
758
759
760
761
      responses:
        200:
          content:
            application/json:
              schema:
Agate's avatar
Agate committed
762
                $ref: "./api/definitions.yml#/License"
Eliot Berriot's avatar
Eliot Berriot committed
763
764
765
766
        404:
          content:
            application/json:
              schema:
Agate's avatar
Agate committed
767
                $ref: "./api/definitions.yml#/ResourceNotFound"
Eliot Berriot's avatar
Eliot Berriot committed
768

769
  /api/v1/libraries/:
770
771
772
773
774
    get:
      summary: List owned libraries
      tags:
        - "Uploads and audio content"
      parameters:
Agate's avatar
Agate committed
775
776
777
778
        - $ref: "./api/parameters.yml#/PageNumber"
        - $ref: "./api/parameters.yml#/PageSize"
        - $ref: "./api/parameters.yml#/Search"
        - $ref: "./api/parameters.yml#/Scope"
779
780
781
782
783
784
      responses:
        200:
          content:
            application/json:
              schema:
                allOf:
Agate's avatar
Agate committed
785
                  - $ref: "./api/definitions.yml#/ResultPage"
786
787
788
789
790
                  - type: "object"
                    properties:
                      results:
                        type: "array"
                        items:
Agate's avatar
Agate committed
791
                          $ref: "./api/definitions.yml#/OwnedLibrary"
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
    post:
      tags:
        - "Uploads and audio content"
      description:
        Create a new library
      responses:
        201:
          $ref: "#/responses/201"
        400:
          $ref: "#/responses/400"
      requestBody:
        required: true
        content:
          application/json:
            schema:
Agate's avatar
Agate committed
807
              $ref: "./api/definitions.yml#/OwnedLibraryCreate"
808

809
  /api/v1/libraries/{uuid}/:
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
    parameters:
      - name: uuid
        in: path
        required: true
        schema:
          type: "string"
          format: "uuid"
    get:
      summary: Retrieve a library
      tags:
        - "Uploads and audio content"
      responses:
        200:
          content:
            application/json:
              schema:
Agate's avatar
Agate committed
826
                $ref: "./api/definitions.yml#/OwnedLibrary"
827
828
829
830
831
832
833
834
835
    post:
      summary: Update a library
      tags:
        - "Uploads and audio content"
      requestBody:
        required: true
        content:
          application/json:
            schema:
Agate's avatar
Agate committed
836
              $ref: "./api/definitions.yml#/OwnedLibraryCreate"
837
      responses:
Eliot Berriot's avatar
Eliot Berriot committed
838
        201:
839
840
841
          content:
            application/json:
              schema:
Agate's avatar
Agate committed
842
                $ref: "./api/definitions.yml#/OwnedLibrary"
843
844
845
846
847
848
849
850
851
852
    delete:
      summary: Delete a library and all associated uploads
      description: |
        This will delete the library, all associated uploads, follows, and broadcast
        the event on the federation.
      tags:
        - "Uploads and audio content"
      responses:
        204:
          $ref: "#/responses/204"
Eliot Berriot's avatar
Eliot Berriot committed
853

854
855
856
857
  /api/v1/channels/:
    get:
      summary: List channels
      tags:
Agate's avatar
Agate committed
858
        - "Channels and subscriptions"
859
      parameters:
Agate's avatar
Agate committed
860
861
862
863
864
865
866
867
        - $ref: "./api/parameters.yml#/PageNumber"
        - $ref: "./api/parameters.yml#/PageSize"
        - $ref: "./api/parameters.yml#/Scope"
        - $ref: "./api/parameters.yml#/Search"
        - $ref: "./api/parameters.yml#/Tags"
        - $ref: "./api/parameters.yml#/Subscribed"
        - $ref: "./api/parameters.yml#/External"
        - $ref: "./api/parameters.yml#/ChannelOrdering"
Agate's avatar
Agate committed
868

869
870
871
872
873
874
      responses:
        200:
          content:
            application/json:
              schema:
                allOf:
Agate's avatar
Agate committed
875
                  - $ref: "./api/definitions.yml#/ResultPage"
876
877
878
879
880
                  - type: "object"
                    properties:
                      results:
                        type: "array"
                        items:
Agate's avatar
Agate committed
881
                          $ref: "./api/definitions.yml#/Channel"
882
883
884
    post:
      summary: Create a new channel
      tags:
Agate's avatar
Agate committed
885
        - "Channels and subscriptions"
886
887
888
889
890
891
892
893
894
895
      responses:
        201:
          $ref: "#/responses/201"
        400:
          $ref: "#/responses/400"
      requestBody:
        required: true
        content:
          application/json:
            schema:
Agate's avatar
Agate committed
896
              $ref: "./api/definitions.yml#/ChannelCreate"
897

Agate's avatar
Agate committed
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
  /api/v1/channels/metadata-choices:
    summary: List metadata (locales, itunes categories) for creating and editing channels.
    tags:
      - "Channels and subscriptions"
    get:
      summary: List channels metadata options
      tags:
        - "Channels and subscriptions"
      responses:
        200:
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  language:
                    type: "array"
                    items:
                      type: object
                      properties:
                        value:
                          type: string
                          description: ID of the locale in ISO 639 format
                          example: "en"
                        language:
                          type: string
                          example: "English"
                  itunes_category:
                    type: "array"
                    items:
                      type: object
                      properties:
                        value:
                          type: string
                          description: ID of the category
                          example: "Business"
                        label:
                          type: string
                          description: Readable label of the category
                          example: "Business"
                        children:
                          type: array
                          description: Some categories have subcategories
                          items:
                            type: string
                            example: "Entrepreneurship"

945
946
947
948
949
950
951
952
953
954
955
  /api/v1/channels/{uuid}/:
    parameters:
      - name: uuid
        in: path
        required: true
        schema:
          type: "string"
          format: "uuid"
    get:
      summary: Retrieve a channel
      tags:
Agate's avatar
Agate committed
956
        - "Channels and subscriptions"
957
958
959
960
961
      responses:
        200:
          content:
            application/json:
              schema:
Agate's avatar
Agate committed
962
                $ref: "./api/definitions.yml#/Channel"
963
964
965
    post:
      summary: Update a channel
      tags:
Agate's avatar
Agate committed
966
        - "Channels and subscriptions"
967
968
969
970
971
      requestBody:
        required: true
        content:
          application/json:
            schema:
Agate's avatar
Agate committed
972
              $ref: "./api/definitions.yml#/ChannelUpdate"
973
974
975
976
977
      responses:
        201:
          content:
            application/json:
              schema:
Agate's avatar
Agate committed
978
                $ref: "./api/definitions.yml#/Channel"
979
980
981
982
983
984
    delete:
      summary: Delete a channel and all associated uploads
      description: |
        This will delete the channel, all associated uploads, follows, and broadcast
        the event on the federation.
      tags:
Agate's avatar
Agate committed
985
        - "Channels and subscriptions"
986
987
988
989
      responses:
        204:
          $ref: "#/responses/204"

Agate's avatar
Agate committed
990
991
992
993
994
995
996
997
998
999
1000
  /api/v1/channels/rss-suscribe/:
    post:
      summary: Subscribe to a third-party podcast via its RSS feed

      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
For faster browsing, not all history is shown. View entire blame