You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

786 lines
20 KiB

  1. # API Reference
  2. SITE_NAME REST API supports listing, creating, updating, pausing and deleting
  3. checks in user's account.
  4. ## API Endpoints
  5. Endpoint Name | Endpoint Address
  6. ------------------------------------------------------|-------
  7. [Get a list of existing checks](#list-checks) | `GET SITE_ROOT/api/v1/checks/`
  8. [Get a single check](#get-check) | `GET SITE_ROOT/api/v1/checks/<uuid>`
  9. [Get a check by its unique_key](#get-check) | `GET SITE_ROOT/api/v1/checks/<unique_key>`
  10. [Create a new check](#create-check) | `POST SITE_ROOT/api/v1/checks/`
  11. [Update an existing check](#update-check) | `POST SITE_ROOT/api/v1/checks/<uuid>`
  12. [Pause monitoring of a check](#pause-check) | `POST SITE_ROOT/api/v1/checks/<uuid>/pause`
  13. [Delete check](#delete-check) | `DELETE SITE_ROOT/api/v1/checks/<uuid>`
  14. [Get a list of checks's logged pings](#list-pings) | `GET SITE_ROOT/api/v1/checks/<uuid>/pings/`
  15. [Get a list of existing integrations](#list-channels) | `GET SITE_ROOT/api/v1/channels/`
  16. ## Authentication
  17. Your requests to SITE_NAME REST API must authenticate using an
  18. API key. Each project in your SITE_NAME account has separate API keys.
  19. There are no account-wide API keys. By default, a project on SITE_NAME doesn't have
  20. an API key. You can create read-write and read-only API keys in the
  21. **Project Settings** page.
  22. Key Type | Description
  23. -------------------|------------
  24. Regular API key | Has full access to all documented API endpoints.
  25. Read-only API key | Only works with the [Get a list of existing checks](#list-checks) and [Get a single check](#get-check) endpoints. Some fields are omitted from the API responses.
  26. The client can authenticate itself by sending an appropriate HTTP
  27. request header. The header's name should be `X-Api-Key` and
  28. its value should be your API key.
  29. Alternatively, for POST requests with a JSON request body,
  30. the client can include an `api_key` field in the JSON document.
  31. See below the "Create a check" section for an example.
  32. ## API Requests
  33. For POST requests, the SITE_NAME API expects request body to be
  34. a JSON document (*not* a `multipart/form-data` encoded form data).
  35. ## API Responses
  36. SITE_NAME uses HTTP status codes wherever possible.
  37. In general, 2xx class indicates success, 4xx indicates an client error,
  38. and 5xx indicates a server error.
  39. The response may contain a JSON document with additional data.
  40. ## Get a List of Existing Checks {: #list-checks .rule }
  41. `GET SITE_ROOT/api/v1/checks/`
  42. Returns a list of checks belonging to the user, optionally filtered by
  43. one or more tags.
  44. ### Query String Parameters
  45. tag=&lt;value&gt;
  46. : Filters the checks, and returns only the checks that are tagged with the
  47. specified value.
  48. This parameter can be repeated multiple times.
  49. Example:
  50. `SITE_ROOT/api/v1/checks/?tag=foo&tag=bar`
  51. ### Response Codes
  52. 200 OK
  53. : The request succeeded.
  54. 401 Unauthorized
  55. : The API key is either missing or invalid.
  56. ### Example Request
  57. ```bash
  58. curl --header "X-Api-Key: your-api-key" SITE_ROOT/api/v1/checks/
  59. ```
  60. ### Example Response
  61. ```json
  62. {
  63. "checks": [
  64. {
  65. "name": "Filesystem Backup",
  66. "tags": "backup fs",
  67. "desc": "Runs incremental backup every hour",
  68. "grace": 600,
  69. "n_pings": 1,
  70. "status": "up",
  71. "last_ping": "2020-03-24T14:02:03+00:00",
  72. "next_ping": "2020-03-24T15:02:03+00:00",
  73. "manual_resume": false,
  74. "ping_url": "PING_ENDPOINT31365bce-8da9-4729-8ff3-aaa71d56b712",
  75. "update_url": "SITE_ROOT/api/v1/checks/31365bce-8da9-4729-8ff3-aaa71d56b712",
  76. "pause_url": "SITE_ROOT/api/v1/checks/31365bce-8da9-4729-8ff3-aaa71d56b712/pause",
  77. "channels": "1bdea468-03bf-47b8-ab27-29a9dd0e4b94,51c6eb2b-2ae1-456b-99fe-6f1e0a36cd3c",
  78. "timeout": 3600
  79. },
  80. {
  81. "name": "Database Backup",
  82. "tags": "production db",
  83. "desc": "Runs ~/db-backup.sh",
  84. "grace": 1200,
  85. "n_pings": 7,
  86. "status": "down",
  87. "last_ping": "2020-03-23T10:19:32+00:00",
  88. "next_ping": null,
  89. "manual_resume": false,
  90. "ping_url": "PING_ENDPOINT803f680d-e89b-492b-82ef-2be7b774a92d",
  91. "update_url": "SITE_ROOT/api/v1/checks/803f680d-e89b-492b-82ef-2be7b774a92d",
  92. "pause_url": "SITE_ROOT/api/v1/checks/803f680d-e89b-492b-82ef-2be7b774a92d/pause",
  93. "channels": "1bdea468-03bf-47b8-ab27-29a9dd0e4b94,51c6eb2b-2ae1-456b-99fe-6f1e0a36cd3c",
  94. "schedule": "15 5 * * *",
  95. "tz": "UTC"
  96. }
  97. ]
  98. }
  99. ```
  100. When using the read-only API key, the following fields are omitted:
  101. `ping_url`, `update_url`, `pause_url`, `channels`. An extra `unique_key` field
  102. is added which can be used [to `GET` a check](#get-check) in place of the `UUID`. The `unique_key` identifier is stable across API calls. Example:
  103. ```json
  104. {
  105. "checks": [
  106. {
  107. "name": "Filesystem Backup",
  108. "tags": "backup fs",
  109. "desc": "Runs incremental backup every hour",
  110. "grace": 600,
  111. "n_pings": 1,
  112. "status": "up",
  113. "last_ping": "2020-03-24T14:02:03+00:00",
  114. "next_ping": "2020-03-24T15:02:03+00:00",
  115. "manual_resume": false,
  116. "unique_key": "a6c7b0a8a66bed0df66abfdab3c77736861703ee",
  117. "timeout": 3600
  118. },
  119. {
  120. "name": "Database Backup",
  121. "tags": "production db",
  122. "desc": "Runs ~/db-backup.sh",
  123. "grace": 1200,
  124. "n_pings": 7,
  125. "status": "down",
  126. "last_ping": "2020-03-23T10:19:32+00:00",
  127. "next_ping": null,
  128. "manual_resume": false,
  129. "unique_key": "124f983e0e3dcaeba921cfcef46efd084576e783",
  130. "schedule": "15 5 * * *",
  131. "tz": "UTC"
  132. }
  133. ]
  134. }
  135. ```
  136. ## Get a Single Check {: #get-check .rule }
  137. `GET SITE_ROOT/api/v1/checks/<uuid>`<br>
  138. `GET SITE_ROOT/api/v1/checks/<unique_key>`
  139. Returns a JSON representation of a single check. Accepts either check's UUID or
  140. the `unique_key` (a field derived from UUID, and returned by API responses when
  141. using the read-only API key) as an identifier.
  142. ### Response Codes
  143. 200 OK
  144. : The request succeeded.
  145. 401 Unauthorized
  146. : The API key is either missing or invalid.
  147. 403 Forbidden
  148. : Access denied, wrong API key.
  149. 404 Not Found
  150. : The specified check does not exist.
  151. ### Example Request
  152. ```bash
  153. curl --header "X-Api-Key: your-api-key" SITE_ROOT/api/v1/checks/<uuid>
  154. ```
  155. ### Example Response
  156. ```json
  157. {
  158. "name": "Database Backup",
  159. "tags": "production db",
  160. "desc": "Runs ~/db-backup.sh",
  161. "grace": 1200,
  162. "n_pings": 7,
  163. "status": "down",
  164. "last_ping": "2020-03-23T10:19:32+00:00",
  165. "next_ping": null,
  166. "manual_resume": false,
  167. "ping_url": "PING_ENDPOINT803f680d-e89b-492b-82ef-2be7b774a92d",
  168. "update_url": "SITE_ROOT/api/v1/checks/803f680d-e89b-492b-82ef-2be7b774a92d",
  169. "pause_url": "SITE_ROOT/api/v1/checks/803f680d-e89b-492b-82ef-2be7b774a92d/pause",
  170. "channels": "1bdea468-03bf-47b8-ab27-29a9dd0e4b94,51c6eb2b-2ae1-456b-99fe-6f1e0a36cd3c",
  171. "schedule": "15 5 * * *",
  172. "tz": "UTC"
  173. }
  174. ```
  175. ### Example Read-Only Response
  176. When using the read-only API key, the following fields are omitted:
  177. `ping_url`, `update_url`, `pause_url`, `channels`. An extra `unique_key` field is
  178. added. This identifier is stable across API calls.
  179. Note: the `ping_url`, `update_url` and `pause_url` fields, although omitted, are not
  180. really secret. The client already knows the check's unique UUID and so can easily
  181. construct these URLs by itself.
  182. ```json
  183. {
  184. "name": "Database Backup",
  185. "tags": "production db",
  186. "desc": "Runs ~/db-backup.sh",
  187. "grace": 1200,
  188. "n_pings": 7,
  189. "status": "down",
  190. "last_ping": "2020-03-23T10:19:32+00:00",
  191. "next_ping": null,
  192. "manual_resume": false,
  193. "unique_key": "124f983e0e3dcaeba921cfcef46efd084576e783",
  194. "schedule": "15 5 * * *",
  195. "tz": "UTC"
  196. }
  197. ```
  198. ## Create a Check {: #create-check .rule }
  199. `POST SITE_ROOT/api/v1/checks/`
  200. Creates a new check and returns its ping URL.
  201. All request parameters are optional and will use their default
  202. values if omitted.
  203. This API call can be used to create both "simple" and "cron" checks.
  204. To create a "simple" check, specify the "timeout" parameter.
  205. To create a "cron" check, specify the "schedule" and "tz" parameters.
  206. ### Request Parameters
  207. name
  208. : string, optional, default value: ""
  209. Name for the new check.
  210. tags
  211. : string, optional, default value: ""
  212. A space-delimited list of tags for the new check.
  213. Example:
  214. <pre>{"tags": "reports staging"}</pre>
  215. desc
  216. : string, optional.
  217. Description for the check.
  218. timeout
  219. : number, optional, default value: {{ default_timeout }}.
  220. A number of seconds, the expected period of this check.
  221. Minimum: 60 (one minute), maximum: 2592000 (30 days).
  222. Example for 5 minute timeout:
  223. <pre>{"kind": "simple", "timeout": 300}</pre>
  224. grace
  225. : number, optional, default value: {{ default_grace }}.
  226. A number of seconds, the grace period for this check.
  227. Minimum: 60 (one minute), maximum: 2592000 (30 days).
  228. schedule
  229. : string, optional, default value: "* * * * *".
  230. A cron expression defining this check's schedule.
  231. If you specify both "timeout" and "schedule" parameters, "timeout" will be
  232. ignored and "schedule" will be used.
  233. Example for a check running every half-hour:
  234. <pre>{"schedule": "0,30 * * * *"}</pre>
  235. tz
  236. : string, optional, default value: "UTC".
  237. Server's timezone. This setting only has effect in combination with the
  238. "schedule" parameter.
  239. Example:
  240. <pre>{"tz": "Europe/Riga"}</pre>
  241. manual_resume
  242. : boolean, optional, default value: false.
  243. Controls whether a paused ping resumes automatically when pinged (the default),
  244. or not. If set to false, a paused check will leave the paused state when it receives
  245. a ping. If set to true, a paused check will ignore pings and stay paused until it is
  246. either manually resumed from the web dashboard or the `manual_resume` flag is
  247. changed.
  248. channels
  249. : string, optional
  250. By default, if a check is created through API, no notification channels
  251. (integrations) are assigned to it. So, when the check goes up or down, no
  252. notifications will get sent.
  253. Set this field to a special value "*" to automatically assign all existing
  254. integrations.
  255. To assign specific integrations, use a comma-separated list of integration
  256. identifiers. Use the [Get a List of Existing Integrations](#list-channels) call to
  257. look up integration identifiers.
  258. unique
  259. : array of string values, optional, default value: [].
  260. Before creating a check, look for existing checks, filtered by fields listed
  261. in `unique`. If a matching check is found, return it with HTTP status code 200.
  262. If no matching check is found, proceed as normal: create a check and return it
  263. with HTTP status code 201.
  264. The accepted values are: `name`, `tags`, `timeout` and `grace`.
  265. Example:
  266. <pre>{"name": "Backups", unique: ["name"]}</pre>
  267. In this example, if a check named "Backups" exists, it will be returned.
  268. Otherwise, a new check will be created and returned.
  269. ### Response Codes
  270. 201 Created
  271. : The check was successfully created.
  272. 200 OK
  273. : The `unique` parameter was used and an existing check was matched.
  274. 400 Bad Request
  275. : The request is not well-formed, violates schema, or uses invalid
  276. field values.
  277. 401 Unauthorized
  278. : The API key is either missing or invalid.
  279. 403 Forbidden
  280. : The account's check limit has been reached. For free accounts,
  281. the limit is 20 checks per account.
  282. ### Example Request
  283. ```bash
  284. curl SITE_ROOT/api/v1/checks/ \
  285. --header "X-Api-Key: your-api-key" \
  286. --data '{"name": "Backups", "tags": "prod www", "timeout": 3600, "grace": 60}'
  287. ```
  288. Or, alternatively:
  289. ```bash
  290. curl SITE_ROOT/api/v1/checks/ \
  291. --data '{"api_key": "your-api-key", "name": "Backups", "tags": "prod www", "timeout": 3600, "grace": 60}'
  292. ```
  293. ### Example Response
  294. ```json
  295. {
  296. "channels": "",
  297. "desc": "",
  298. "grace": 60,
  299. "last_ping": null,
  300. "n_pings": 0,
  301. "name": "Backups",
  302. "next_ping": null,
  303. "manual_resume": false,
  304. "pause_url": "SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc/pause",
  305. "ping_url": "PING_ENDPOINTf618072a-7bde-4eee-af63-71a77c5723bc",
  306. "status": "new",
  307. "tags": "prod www",
  308. "timeout": 3600,
  309. "update_url": "SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc",
  310. }
  311. ```
  312. ## Update an Existing Check {: #update-check .rule }
  313. `POST SITE_ROOT/api/v1/checks/<uuid>`
  314. Updates an existing check. All request parameters are optional. The check is
  315. updated only with the supplied request parameters. If any parameter is omitted,
  316. its value is left unchanged.
  317. ### Request Parameters
  318. name
  319. : string, optional.
  320. Name for the check.
  321. tags
  322. : string, optional.
  323. A space-delimited list of tags for the check.
  324. Example:
  325. <pre>{"tags": "reports staging"}</pre>
  326. desc
  327. : string, optional.
  328. Description for the check.
  329. timeout
  330. : number, optional.
  331. A number of seconds, the expected period of this check.
  332. Minimum: 60 (one minute), maximum: 2592000 (30 days).
  333. Example for 5 minute timeout:
  334. <pre>{"kind": "simple", "timeout": 300}</pre>
  335. grace
  336. : number, optional.
  337. A number of seconds, the grace period for this check.
  338. Minimum: 60 (one minute), maximum: 2592000 (30 days).
  339. schedule
  340. : string, optional.
  341. A cron expression defining this check's schedule.
  342. If you specify both "timeout" and "schedule" parameters, "timeout" will be
  343. ignored and "schedule" will be used.
  344. Example for a check running every half-hour:
  345. <pre>{"schedule": "0,30 * * * *"}</pre>
  346. tz
  347. : string, optional.
  348. Server's timezone. This setting only has effect in combination with the
  349. "schedule" parameter.
  350. Example:
  351. <pre>{"tz": "Europe/Riga"}</pre>
  352. manual_resume
  353. : boolean, optional, default value: false.
  354. Controls whether a paused ping resumes automatically when pinged (the default),
  355. or not. If set to false, a paused check will leave the paused state when it receives
  356. a ping. If set to true, a paused check will ignore pings and stay paused until it is
  357. either manually resumed from the web dashboard or the `manual_resume` flag is
  358. changed.
  359. channels
  360. : string, optional.
  361. Set this field to a special value "*" to automatically assign all existing
  362. notification channels.
  363. Set this field to a special value "" (empty string) to automatically *unassign*
  364. all notification channels.
  365. Set this field to a comma-separated list of channel identifiers to assign
  366. specific notification channels.
  367. Example:
  368. <pre>{"channels": "4ec5a071-2d08-4baa-898a-eb4eb3cd6941,746a083e-f542-4554-be1a-707ce16d3acc"}</pre>
  369. ### Response Codes
  370. 200 OK
  371. : The check was successfully updated.
  372. 400 Bad Request
  373. : The request is not well-formed, violates schema, or uses invalid
  374. field values.
  375. 401 Unauthorized
  376. : The API key is either missing or invalid.
  377. 403 Forbidden
  378. : Access denied, wrong API key.
  379. 404 Not Found
  380. : The specified check does not exist.
  381. ### Example Request
  382. ```bash
  383. curl SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc \
  384. --header "X-Api-Key: your-api-key" \
  385. --data '{"name": "Backups", "tags": "prod www", "timeout": 3600, "grace": 60}'
  386. ```
  387. Or, alternatively:
  388. ```bash
  389. curl SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc \
  390. --data '{"api_key": "your-api-key", "name": "Backups", "tags": "prod www", "timeout": 3600, "grace": 60}'
  391. ```
  392. ### Example Response
  393. ```json
  394. {
  395. "channels": "",
  396. "desc": "",
  397. "grace": 60,
  398. "last_ping": null,
  399. "n_pings": 0,
  400. "name": "Backups",
  401. "next_ping": null,
  402. "manual_resume": false,
  403. "pause_url": "SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc/pause",
  404. "ping_url": "PING_ENDPOINTf618072a-7bde-4eee-af63-71a77c5723bc",
  405. "status": "new",
  406. "tags": "prod www",
  407. "timeout": 3600,
  408. "update_url": "SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc",
  409. }
  410. ```
  411. ## Pause Monitoring of a Check {: #pause-check .rule }
  412. `POST SITE_ROOT/api/v1/checks/<uuid>/pause`
  413. Disables monitoring for a check, without removing it. The check goes into a "paused"
  414. state. You can resume monitoring of the check by pinging it.
  415. This API call has no request parameters.
  416. ### Response Codes
  417. 200 OK
  418. : The check was successfully paused.
  419. 401 Unauthorized
  420. : The API key is either missing or invalid.
  421. 403 Forbidden
  422. : Access denied, wrong API key.
  423. 404 Not Found
  424. : The specified check does not exist.
  425. ### Example Request
  426. ```bash
  427. curl SITE_ROOT/api/v1/checks/0c8983c9-9d73-446f-adb5-0641fdacc9d4/pause \
  428. --request POST --header "X-Api-Key: your-api-key" --data ""
  429. ```
  430. Note: the `--data ""` argument forces curl to send a `Content-Length` request header
  431. even though the request body is empty. For HTTP POST requests, the `Content-Length`
  432. header is sometimes required by some network proxies and web servers.
  433. ### Example Response
  434. ```json
  435. {
  436. "channels": "",
  437. "desc": "",
  438. "grace": 60,
  439. "last_ping": null,
  440. "n_pings": 0,
  441. "name": "Backups",
  442. "next_ping": null,
  443. "manual_resume": false,
  444. "pause_url": "SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc/pause",
  445. "ping_url": "PING_ENDPOINTf618072a-7bde-4eee-af63-71a77c5723bc",
  446. "status": "paused",
  447. "tags": "prod www",
  448. "timeout": 3600,
  449. "update_url": "SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc"
  450. }
  451. ```
  452. ## Delete Check {: #delete-check .rule }
  453. `DELETE SITE_ROOT/api/v1/checks/<uuid>`
  454. Permanently deletes the check from user's account. Returns JSON representation of the
  455. check that was just deleted.
  456. This API call has no request parameters.
  457. ### Response Codes
  458. 200 OK
  459. : The check was successfully deleted.
  460. 401 Unauthorized
  461. : The API key is either missing or invalid.
  462. 403 Forbidden
  463. : Access denied, wrong API key.
  464. 404 Not Found
  465. : The specified check does not exist.
  466. ### Example Request
  467. ```bash
  468. curl SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc \
  469. --request DELETE --header "X-Api-Key: your-api-key"
  470. ```
  471. ### Example Response
  472. ```json
  473. {
  474. "channels": "",
  475. "desc": "",
  476. "grace": 60,
  477. "last_ping": null,
  478. "n_pings": 0,
  479. "name": "Backups",
  480. "next_ping": null,
  481. "manual_resume": false,
  482. "pause_url": "SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc/pause",
  483. "ping_url": "PING_ENDPOINTf618072a-7bde-4eee-af63-71a77c5723bc",
  484. "status": "new",
  485. "tags": "prod www",
  486. "timeout": 3600,
  487. "update_url": "SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc",
  488. }
  489. ```
  490. ## Get a list of checks's logged pings {: #list-pings .rule }
  491. `GET SITE_ROOT/api/v1/checks/<uuid>/pings/`
  492. Returns a list of pings this check has received.
  493. This endpoint returns pings in reverse order (most recent first), and the total
  494. number of returned pings depends on account's billing plan: 100 for free accounts,
  495. 1000 for paid accounts.
  496. ### Response Codes
  497. 200 OK
  498. : The request succeeded.
  499. 401 Unauthorized
  500. : The API key is either missing or invalid.
  501. 403 Forbidden
  502. : Access denied, wrong API key.
  503. 404 Not Found
  504. : The specified check does not exist.
  505. ### Example Request
  506. ```bash
  507. curl SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc/pings/ \
  508. --header "X-Api-Key: your-api-key"
  509. ```
  510. ### Example Response
  511. ```json
  512. {
  513. "pings": [
  514. {
  515. "type": "success",
  516. "date": "2020-06-09T14:51:06.113073+00:00",
  517. "n": 4,
  518. "scheme": "http",
  519. "remote_addr": "192.0.2.0",
  520. "method": "GET",
  521. "ua": "curl/7.68.0",
  522. "duration": 2.896736
  523. },
  524. {
  525. "type": "start",
  526. "date": "2020-06-09T14:51:03.216337+00:00",
  527. "n": 3,
  528. "scheme": "http",
  529. "remote_addr": "192.0.2.0",
  530. "method": "GET",
  531. "ua": "curl/7.68.0"
  532. },
  533. {
  534. "type": "success",
  535. "date": "2020-06-09T14:50:59.633577+00:00",
  536. "n": 2,
  537. "scheme": "http",
  538. "remote_addr": "192.0.2.0",
  539. "method": "GET",
  540. "ua": "curl/7.68.0",
  541. "duration": 2.997976
  542. },
  543. {
  544. "type": "start",
  545. "date": "2020-06-09T14:50:56.635601+00:00",
  546. "n": 1,
  547. "scheme": "http",
  548. "remote_addr": "192.0.2.0",
  549. "method": "GET",
  550. "ua": "curl/7.68.0"
  551. }
  552. ]
  553. }
  554. ```
  555. ## Get a List of Existing Integrations {: #list-channels .rule }
  556. `GET SITE_ROOT/api/v1/channels/`
  557. Returns a list of integrations belonging to the project.
  558. ### Response Codes
  559. 200 OK
  560. : The request succeeded.
  561. 401 Unauthorized
  562. : The API key is either missing or invalid.
  563. ### Example Request
  564. ```bash
  565. curl --header "X-Api-Key: your-api-key" SITE_ROOT/api/v1/channels/
  566. ```
  567. ### Example Response
  568. ```json
  569. {
  570. "channels": [
  571. {
  572. "id": "4ec5a071-2d08-4baa-898a-eb4eb3cd6941",
  573. "name": "My Work Email",
  574. "kind": "email"
  575. },
  576. {
  577. "id": "746a083e-f542-4554-be1a-707ce16d3acc",
  578. "name": "My Phone",
  579. "kind": "sms"
  580. }
  581. ]
  582. }
  583. ```