Files
Lauri Ojansivu b7589737f5 File docs/Features the way the WeKan menus are.
A feature's guide now sits under the menu it is used from, read from the
templates rather than from where somebody once put it: Header-Bar,
All-Boards, Pages, Board-Header (search and every Board View), Board-Sidebar
(Board Settings, Filter, Members, Labels, Archive), Rules, Swimlanes, Lists,
Cards, Member-Settings, Admin-Panel and Login-Page. Topics used from several
menus (editor, history, theme, translations, email, troubleshooting) are in
General.

- Each area has a README mapping its menu entries to their guides and to the
  template or server module that implements them. Board-Header/README.md
  lists all 40 Board View entries with the template boardBody.jade renders;
  five views (Table, Calendar Mode, Time, Timeline, Map) have no guide of
  their own yet and say so.
- Board-View.md listed 25 views while BOARD_VIEWS has 40; it now lists all
  of them with their English labels.
- Pages keep their file names. Where a released changelog links an old path,
  a "# Moved" page stays there and points to the new one; test-menu.sh skips
  folders holding only those.
- Undo was filed under Login; it is General/Undo now.
- Every link in docs, code comments, scripts and tests follows the move;
  docsLinksResolve checks them all.

Tests that read a doc follow it to its new place. boardViewSettings now fails
when Board-View.md or Board-Header/README.md differs from BOARD_VIEWS, or
names a template boardBody.jade does not render.

Thanks to xet7 !
2026-10-16 23:45:35 +03:00

604 lines
23 KiB
Markdown

REST API is not complete yet, please add missing functionality with pull requests to devel branch.
If you are in a hurry, you can use these to have more functionality:
* https://restheart.org
* http://vulcanjs.org
For workflows see [If-this-then-that issue](https://github.com/wekan/wekan/issues/1160) than mentions Huginn, Flogo etc.
# Wekan REST API
The REST API allows you to control and extend Wekan with ease.
If you are an end-user and not a dev or a tester, [create an issue](https://github.com/wekan/wekan/issues/new) to request new APIs.
> All API calls in the documentation are made using `curl`. However, you are free to use Java / Python / PHP / Golang / Ruby / Swift / Objective-C / Rust / Scala / C# or any other programming languages.
## Production Security Concerns
When calling a production Wekan server, ensure it is running via HTTPS and has a valid SSL Certificate. The login method requires you to post your username and password in plaintext, which is why we highly suggest only calling the REST login api over HTTPS. Also, few things to note:
* Only call via HTTPS
* Implement a timed authorization token expiration strategy
* Ensure the calling user only has permissions for what they are calling and no more
# Summary
### Authentication
| HTTP Method | Url | Short Description |
| :--- | :--- | :--- |
| `POST` | `/users/login` | [Authenticate with the REST API.](#login) |
### Users
| HTTP Method | Url | Short Description |
| :--- | :--- | :--- |
| `POST` | `/users/register` | [Register a new user.](User.md#user-register) |
| `POST` | `/api/users` | [Create a new user.](User.md#user-create) |
| `PUT` | `/api/users/:id` | [Disable an existing user.](User.md#disable-a-user-the-user-is-not-allowed-to-login-and-his-login-tokens-are-purged) |
| `PUT` | `/api/users/:id` | [Enable an existing user.](User.md#enable-a-user) |
| `PUT` | `/api/users/:id` | [Admin takes the ownership.](User.md#the-admin-takes-the-ownership-of-all-boards-of-the-user-archived-and-not-archived-where-the-user-is-admin-on) |
| `DELETE` | `/api/users/:id` | [Delete an existing user.](User.md#user-delete) ([Warning](https://github.com/wekan/wekan/issues/1289))|
| `GET` | `/api/users/:id` | [Gets a user's information.](User.md#user-information) |
| `GET` | `/api/users` | [All of the users.](User.md#user-list) |
| `GET` | `/api/user` | [Gets a logged-in user.](User.md#user-logged-in) |
### Cards
| HTTP Method | Url | Short Description |
| :--- | :--- | :--- |
| `POST` | `/api/boards/:boardId/lists/:listId/cards` | [Add a card to a list, board, and swimlane.](Cards.md#add-card-to-list-board-swimlane) |
| `PUT` | `/api/boards/:boardId/lists/:fromListId/cards/:cardId` | [Update a card.](Cards.md#update-a-card) |
| `DELETE` | `/api/boards/:boardId/lists/:listId/cards/:cardId` | [Delete a card.](Cards.md#update-a-card) |
### Rules (Board Automation / IFTTT)
| HTTP Method | Url | Short Description |
| :--- | :--- | :--- |
| `GET` | `/api/boards/:boardId/rules` | [List all automation rules of a board.](Rules.md#list-rules) |
| `GET` | `/api/boards/:boardId/rules/:ruleId` | [Get one rule with its trigger and action.](Rules.md#get-one-rule) |
| `POST` | `/api/boards/:boardId/rules` | [Add an automation rule, e.g. add/remove a member when a card is moved to/from a list (#2674).](Rules.md#add-a-rule) |
| `PUT` | `/api/boards/:boardId/rules/:ruleId` | [Edit a rule's title, trigger and/or action.](Rules.md#edit-a-rule) |
| `DELETE` | `/api/boards/:boardId/rules/:ruleId` | [Remove a rule and its trigger and action.](Rules.md#delete-a-rule) |
### Board Domain Sharing
| HTTP Method | Url | Short Description |
| :--- | :--- | :--- |
| `GET` | `/api/boards/:boardId/domains` | [List the email domains a board is shared with.](#list-board-domains) |
| `POST` | `/api/boards/:boardId/domains` | [Share a board with an email domain.](#add-a-board-domain) |
| `DELETE` | `/api/boards/:boardId/domains/:domain` | [Stop sharing a board with an email domain.](#remove-a-board-domain) |
### GlobalAdmin Settings
| HTTP Method | Url | Short Description |
| :--- | :--- | :--- |
| `GET` | `/api/settings` | [Read the Admin Panel global settings.](#get-settings) |
| `PUT` | `/api/settings` | [Update the Admin Panel global settings.](#update-settings) |
### Attachments
| HTTP Method | Url | Short Description |
| :--- | :--- | :--- |
| `GET` | `/api/boards/:boardId/attachments` | List the live attachments of a board. |
| `GET` | `/api/boards/:boardId/attachments/deleted` | [List the soft-deleted attachments of a board.](#list-deleted-attachments) |
| `DELETE` | `/api/boards/:boardId/attachments/:attachmentId` | [Soft-delete an attachment.](#soft-delete-an-attachment) |
| `POST` | `/api/boards/:boardId/attachments/:attachmentId/restore` | [Restore a soft-deleted attachment.](#restore-an-attachment) |
| `POST` | `/api/attachment/upload` | Upload a file to a card: raw body, streamed, or base64 JSON. See [Attachments.md](./Attachments.md). |
| `GET` | `/api/attachment/download/:attachmentId` | Download a card's file: `?raw=1` streams the file itself. See [Attachments.md](./Attachments.md). |
| `POST` | `/api/attachment/upload-background` | Upload and set a board background, raw or JSON. See [Attachments.md](./Attachments.md). |
| `GET` | `/api/attachment/download-background/:boardId` | Download a board background, `?raw=1` for the image itself. See [Attachments.md](./Attachments.md). |
### Board Settings: card field order
| HTTP Method | Url | Short Description |
| :--- | :--- | :--- |
| `GET` | `/api/boards/:boardId/cardFieldOrder` | [Get the order of the opened card's sections.](#get-the-card-field-order) |
| `PUT` | `/api/boards/:boardId/cardFieldOrder` | [Set the order of the opened card's sections.](#set-the-card-field-order) |
### Board Settings: Board View
| HTTP Method | Url | Short Description |
| :--- | :--- | :--- |
| `GET` | `/api/boards/:boardId/boardViewSettings` | [Get which Board View menu entries a board offers, its defaults and their order.](#get-the-board-view-settings) |
| `PUT` | `/api/boards/:boardId/boardViewSettings` | [Set which views are offered, which is the default, and the menu order.](#set-the-board-view-settings) |
### Admin Panel: Problems
| HTTP Method | Url | Short Description |
| :--- | :--- | :--- |
| `GET` | `/api/admin/problems` | [The Problems status overview and new-problem counts.](#problems-overview) |
| `GET` | `/api/admin/problems/:stream` | [One page of a problem stream.](#problem-stream) |
| `POST` | `/api/admin/problems/:stream/acknowledge` | [Acknowledge a stream's new problems.](#acknowledge-a-stream) |
### Admin Panel: OAuth login providers and passwordless
| HTTP Method | Url | Short Description |
| :--- | :--- | :--- |
| `GET` | `/api/admin/oauth-providers` | [Which source is in effect for every provider setting.](#get-oauth-provider-settings) |
| `PUT` | `/api/admin/oauth-providers/:providerKey` | [Update one provider's Admin Panel settings.](#update-an-oauth-provider) |
| `PUT` | `/api/admin/passwordless` | [Turn passwordless login on or off.](#passwordless) |
---
# Login
| URL | Requires Auth | HTTP Method |
| :--- | :--- | :--- |
| `/users/login` | `no` | `POST` |
## Payload
### Authentication with username
| Argument | Example | Required | Description |
| :--- | :--- | :--- | :--- |
| `username` | `myusername` | Required | Your username |
| `password` | `my$up3erP@ssw0rd` | Required | Your password |
### Authentication with email
| Argument | Example | Required | Description |
| :--- | :--- | :--- | :--- |
| `email` | `my@email.com` | Required | Your email |
| `password` | `my$up3erP@ssw0rd` | Required | Your password |
* Notes:
* **You will need to provide the `token` for any of the authenticated methods.**
## Example Call - As Form Data
DOES NOT WORK ! Please use As JSON example below !
https://github.com/wekan/wekan/issues/4807
```bash
curl http://localhost:3000/users/login \
-d "username=myusername&password=mypassword"
```
```bash
curl http://localhost:3000/users/login \
-d "email=my@email.com&password=mypassword"
```
## Example Call - As JSON
THIS WORKS !! Alternatively, look at api.py example at https://github.com/wekan/wekan
NOTE: Username and password is case sensitive. So type BIG and small letters correctly.
```bash
curl -H "Content-type:application/json" \
http://localhost:3000/users/login \
-d '{ "username": "myusername", "password": "mypassword" }'
```
```bash
curl -H "Content-type:application/json" \
http://localhost:3000/users/login \
-d '{ "email": "my@email.com", "password": "mypassword" }'
```
## Result
```json
{
"id": "user id",
"token": "string",
"tokenExpires": "ISO encoded date string"
}
```
## Result example
```json
{
"id": "XQMZgynx9M79qTtQc",
"token": "ExMp2s9ML1JNp_l11sIfINPT3wykZ1SsVwg-cnxKdc8",
"tokenExpires": "2017-12-15T00:47:26.303Z"
}
```
---
# Board Domain Sharing
Boards can be shared with every user on an email **domain** (for example everyone
with an `@example.com` address). These endpoints list, add and remove the domains a
board is shared with.
A board admin (or a site admin) is required to add or remove domains. Domains are
validated: they are stored lowercase, must contain a `.`, and must not contain `@`
or whitespace.
The matching `api.py` commands are `boarddomains`, `addboarddomain` and
`removeboarddomain`.
## List board domains
| URL | Requires Auth | HTTP Method |
| :--- | :--- | :--- |
| `/api/boards/:boardId/domains` | `yes` | `GET` |
```bash
curl -H "Authorization: Bearer t7iYB86mXoLfP_XsMegxF41oKT7iiA9lDYiKVtXcctl" \
http://localhost:3000/api/boards/abcd1234/domains
```
## Add a board domain
| URL | Requires Auth (board admin) | HTTP Method |
| :--- | :--- | :--- |
| `/api/boards/:boardId/domains` | `yes` | `POST` |
```bash
curl -H "Authorization: Bearer t7iYB86mXoLfP_XsMegxF41oKT7iiA9lDYiKVtXcctl" \
-H "Content-type:application/json" \
-X POST \
http://localhost:3000/api/boards/abcd1234/domains \
-d '{ "domain": "example.com" }'
```
## Remove a board domain
| URL | Requires Auth (board admin) | HTTP Method |
| :--- | :--- | :--- |
| `/api/boards/:boardId/domains/:domain` | `yes` | `DELETE` |
```bash
curl -H "Authorization: Bearer t7iYB86mXoLfP_XsMegxF41oKT7iiA9lDYiKVtXcctl" \
-X DELETE \
http://localhost:3000/api/boards/abcd1234/domains/example.com
```
---
# GlobalAdmin Settings
These endpoints read and update the **Admin Panel** global settings (registration,
product name, logos, custom head / manifest, accessibility and support pages, and
so on). They are **global-admin only**.
Updates are applied through a field **whitelist**, so only the supported settings
fields can be changed. For security, `mailServer` / SMTP credentials are **never
returned** by `GET` and are **never writable** by `PUT`.
The matching `api.py` commands are `getsettings` and `editsettings <field> <value>`.
## Get settings
| URL | Requires Auth (global admin) | HTTP Method |
| :--- | :--- | :--- |
| `/api/settings` | `yes` | `GET` |
```bash
curl -H "Authorization: Bearer t7iYB86mXoLfP_XsMegxF41oKT7iiA9lDYiKVtXcctl" \
http://localhost:3000/api/settings
```
## Update settings
| URL | Requires Auth (global admin) | HTTP Method |
| :--- | :--- | :--- |
| `/api/settings` | `yes` | `PUT` |
```bash
curl -H "Authorization: Bearer t7iYB86mXoLfP_XsMegxF41oKT7iiA9lDYiKVtXcctl" \
-H "Content-type:application/json" \
-X PUT \
http://localhost:3000/api/settings \
-d '{ "productName": "My WeKan", "disableRegistration": true }'
```
---
# Attachments
Deleting an attachment from a card is a **soft delete** (see
[History.md §12](../Features/General/History/History.md)): the file is kept,
the card and the minicard badge hide it, and the card history - or this API -
restores it. There is **no hard delete of a single attachment** over the API;
the one hard delete is deleting an archived board with Admin Panel / Problems /
Delete enabled. All three endpoints go through the same server methods the
card and the card history use, so the permission check, the cover unset and
the history row are the ones the UI gets.
## List deleted attachments
| URL | Requires Auth (board access) | HTTP Method |
| :--- | :--- | :--- |
| `/api/boards/:boardId/attachments/deleted` | `yes` | `GET` |
```bash
curl -H "Authorization: Bearer t7iYB86mXoLfP_XsMegxF41oKT7iiA9lDYiKVtXcctl" \
http://localhost:3000/api/boards/BOARDID/attachments/deleted
```
Result:
```json
[
{
"attachmentId": "sKHd9a2vLQ7Wq3xPz",
"attachmentName": "spec.pdf",
"attachmentType": "application/pdf",
"boardId": "BOARDID",
"swimlaneId": "yhY4RJmoZ2P7hFjQm",
"listId": "vFnjPvQHnKf2EzRfE",
"cardId": "a2oXL5HGdVTZuTjxi",
"deletedAt": "2026-09-11T10:12:41.203Z",
"deletedBy": "USERID",
"deleteBatchId": "attachment-1789107161203-USERID"
}
]
```
The live attachments are listed by `GET /api/boards/:boardId/attachments`.
## Soft-delete an attachment
| URL | Requires Auth (may edit the card) | HTTP Method |
| :--- | :--- | :--- |
| `/api/boards/:boardId/attachments/:attachmentId` | `yes` | `DELETE` |
```bash
curl -H "Authorization: Bearer t7iYB86mXoLfP_XsMegxF41oKT7iiA9lDYiKVtXcctl" \
-X DELETE \
http://localhost:3000/api/boards/BOARDID/attachments/ATTACHMENTID
```
Result: `{ "deleted": true, "batchId": "attachment-1789107161203-USERID" }`.
Idempotent: an attachment that is already deleted is left as it is. If the
attachment was the card's cover, the cover is unset.
## Restore an attachment
| URL | Requires Auth (may edit the card) | HTTP Method |
| :--- | :--- | :--- |
| `/api/boards/:boardId/attachments/:attachmentId/restore` | `yes` | `POST` |
```bash
curl -H "Authorization: Bearer t7iYB86mXoLfP_XsMegxF41oKT7iiA9lDYiKVtXcctl" \
-X POST \
http://localhost:3000/api/boards/BOARDID/attachments/ATTACHMENTID/restore
```
Result: `{ "restored": true }` (`false` when the attachment was not deleted).
The cover is never re-set by a restore.
---
# Board Settings: card field order
The opened card draws its Labels, Dates, Members, Custom Fields and Description
sections in the order Board Settings sets. Whatever is stored, the order in
effect always contains each of the five keys exactly once: unknown keys are
dropped, duplicates keep their first position, and a missing key is appended in
its default position.
## Get the card field order
| URL | Requires Auth (board access) | HTTP Method |
| :--- | :--- | :--- |
| `/api/boards/:boardId/cardFieldOrder` | `yes` | `GET` |
```bash
curl -H "Authorization: Bearer t7iYB86mXoLfP_XsMegxF41oKT7iiA9lDYiKVtXcctl" \
http://localhost:3000/api/boards/BOARDID/cardFieldOrder
```
Result:
```json
{
"cardFieldOrder": ["labels", "dates", "members", "customFields", "description"],
"keys": ["labels", "dates", "members", "customFields", "description"]
}
```
## Set the card field order
| URL | Requires Auth (board admin) | HTTP Method |
| :--- | :--- | :--- |
| `/api/boards/:boardId/cardFieldOrder` | `yes` | `PUT` |
```bash
curl -H "Authorization: Bearer t7iYB86mXoLfP_XsMegxF41oKT7iiA9lDYiKVtXcctl" \
-H "Content-type:application/json" \
-X PUT \
http://localhost:3000/api/boards/BOARDID/cardFieldOrder \
-d '{ "cardFieldOrder": ["description", "customFields", "labels", "dates", "members"] }'
```
Returns the order in effect, in the same shape as `GET`.
---
# Board Settings: Board View
Which entries of the **Board View** menu a board offers and which one it
opens in, separately for when the board is public and when it is private, and
the order the menu lists them in - the [Board View settings](../Features/Board-Sidebar/Board-Settings/Board-View.md)
popup over the API. Both endpoints answer the state in effect, the way the
menu renders it: every view key exactly once with both `showOnPublic` and
`showOnPrivate` explicit (a board that never opened the popup shows every
view), the two defaults resolved (missing or unknown reads as
`board-view-swimlanes`), and `boardViewOrder` made whole (unknown keys
dropped, missing views appended in default order). `keys` lists the known
view keys.
## Get the Board View settings
| URL | Requires Auth (board access) | HTTP Method |
| :--- | :--- | :--- |
| `/api/boards/:boardId/boardViewSettings` | `yes` | `GET` |
```bash
curl -H "Authorization: Bearer t7iYB86mXoLfP_XsMegxF41oKT7iiA9lDYiKVtXcctl" \
http://localhost:3000/api/boards/BOARDID/boardViewSettings
```
Result (shortened):
```json
{
"boardViewSettings": {
"board-view-swimlanes": { "showOnPublic": true, "showOnPrivate": true },
"board-view-lists": { "showOnPublic": true, "showOnPrivate": true },
"board-view-table": { "showOnPublic": false, "showOnPrivate": true },
"...": {}
},
"defaultPublicBoardView": "board-view-swimlanes",
"defaultPrivateBoardView": "board-view-swimlanes",
"boardViewOrder": ["board-view-swimlanes", "board-view-lists", "board-view-table", "..."],
"keys": ["board-view-swimlanes", "board-view-lists", "board-view-table", "..."]
}
```
## Set the Board View settings
| URL | Requires Auth (board admin) | HTTP Method |
| :--- | :--- | :--- |
| `/api/boards/:boardId/boardViewSettings` | `yes` | `PUT` |
The body is any subset of `boardViewSettings`, `defaultPublicBoardView`,
`defaultPrivateBoardView` and `boardViewOrder`; keys not sent are left as
they are. The rules are the popup's:
- a default is always shown on its side: setting a default also ticks its
*Show* box, and hiding a side's current default is refused with `400` -
set another default first (or in the same request: defaults are applied
before the show flags, so one request can move the default and hide the
old one);
- an unknown view key anywhere in the body is a `400`, and nothing of that
request is applied;
- `boardViewOrder` is normalised so the menu lists every view exactly once:
the keys sent come first in the order given, the rest follow in default
order;
- a body with none of the four keys is a `400`.
```bash
curl -H "Authorization: Bearer t7iYB86mXoLfP_XsMegxF41oKT7iiA9lDYiKVtXcctl" \
-H "Content-type:application/json" \
-X PUT \
http://localhost:3000/api/boards/BOARDID/boardViewSettings \
-d '{
"defaultPublicBoardView": "board-view-roadmap",
"boardViewSettings": {
"board-view-swimlanes": { "showOnPublic": false },
"board-view-table": { "showOnPublic": false, "showOnPrivate": true }
},
"boardViewOrder": ["board-view-roadmap", "board-view-gantt"]
}'
```
Returns the settings in effect, in the same shape as `GET`. A refusal:
```json
{ "error": "boardViewSettings.board-view-swimlanes.showOnPublic: cannot hide the public default view; set defaultPublicBoardView to another view first" }
```
---
# Admin Panel: Problems
The **Admin Panel → Problems** pages over the API, **global-admin only** and
read-only apart from acknowledging a stream. Each row of a stream is a
summary that accumulates (`count`, `firstAt`..`at`, `actors`), never a row per
event - see [Problems](../Features/Admin-Panel/Problems/README.md).
## Problems overview
| URL | Requires Auth (global admin) | HTTP Method |
| :--- | :--- | :--- |
| `/api/admin/problems` | `yes` | `GET` |
```bash
curl -H "Authorization: Bearer t7iYB86mXoLfP_XsMegxF41oKT7iiA9lDYiKVtXcctl" \
http://localhost:3000/api/admin/problems
```
Result:
```json
{
"inProgress": [{ "kind": "board-repair", "active": true, "message": "Board data-repair — 12/146 boards" }],
"problems": [{ "id": "broken-cards", "severity": "warning", "count": 3, "title": "Broken cards", "detail": "..." }],
"newProblems": [{ "stream": "security", "count": 2 }, { "stream": "database", "count": 1 }],
"streams": ["security", "speed", "tests", "cpu", "database", "integrity"]
}
```
## Problem stream
| URL | Requires Auth (global admin) | HTTP Method |
| :--- | :--- | :--- |
| `/api/admin/problems/:stream` | `yes` | `GET` |
`:stream` is one of `security`, `speed`, `tests`, `cpu`, `database`,
`integrity` or `api` (the REST API usage report). Query parameters: `limit`
(1..200, default 50), `skip` (default 0) and `search` (case-insensitive text
over the columns the page shows).
```bash
curl -H "Authorization: Bearer t7iYB86mXoLfP_XsMegxF41oKT7iiA9lDYiKVtXcctl" \
"http://localhost:3000/api/admin/problems/database?limit=20&search=disk"
```
Result: `{ "stream": "database", "total": 1, "limit": 20, "skip": 0, "rows": [ ... ] }`.
## Acknowledge a stream
| URL | Requires Auth (global admin) | HTTP Method |
| :--- | :--- | :--- |
| `/api/admin/problems/:stream/acknowledge` | `yes` | `POST` |
```bash
curl -H "Authorization: Bearer t7iYB86mXoLfP_XsMegxF41oKT7iiA9lDYiKVtXcctl" \
-X POST \
http://localhost:3000/api/admin/problems/security/acknowledge
```
Result: `{ "acknowledged": "security" }`. The overview then reports zero new
problems for the stream until the next one is recorded.
---
# Admin Panel: OAuth login providers and passwordless
The **Admin Panel / People / Login** section for Meteor's own accounts-*
login services (Google, GitHub, Facebook, X/Twitter, Meteor Developer, Weibo,
Meetup) and passwordless email codes - see
[OAuth Providers](../Features/Login-Page/OAuth-Providers.md) and
[Passwordless](../Features/Login-Page/Passwordless.md). **Global-admin only.** A
value saved here wins over the `OAUTH_*` / `PASSWORDLESS_ENABLED` environment
variable and takes effect without a restart. **A provider's secret is never
returned**: it is reported only as `{ "source", "hasValue" }`.
## Get OAuth provider settings
| URL | Requires Auth (global admin) | HTTP Method |
| :--- | :--- | :--- |
| `/api/admin/oauth-providers` | `yes` | `GET` |
```bash
curl -H "Authorization: Bearer t7iYB86mXoLfP_XsMegxF41oKT7iiA9lDYiKVtXcctl" \
http://localhost:3000/api/admin/oauth-providers
```
Result (`source` is `env`, `admin` or `unset`):
```json
{
"providers": {
"google": {
"enabled": { "source": "admin", "value": true },
"id": { "source": "env", "value": "1234.apps.googleusercontent.com" },
"secret": { "source": "env", "hasValue": true }
},
"github": { "enabled": { "source": "unset", "value": null }, "id": { "source": "unset", "value": null }, "secret": { "source": "unset", "hasValue": false } }
},
"loginStyle": { "source": "env", "value": "redirect" },
"mergeExistingUsers": { "source": "unset", "value": null },
"passwordless": { "source": "admin", "value": false }
}
```
## Update an OAuth provider
| URL | Requires Auth (global admin) | HTTP Method |
| :--- | :--- | :--- |
| `/api/admin/oauth-providers/:providerKey` | `yes` | `PUT` |
`:providerKey` is one of `google`, `github`, `facebook`, `twitter`,
`meteor-developer`, `weibo`, `meetup`. Body fields, all optional: `enabled`,
`id`, `secret` (an empty or missing secret keeps the stored one), `loginStyle`
(`popup` or `redirect`), and the two settings shared by every provider,
`globalLoginStyle` and `mergeExistingUsers`.
```bash
curl -H "Authorization: Bearer t7iYB86mXoLfP_XsMegxF41oKT7iiA9lDYiKVtXcctl" \
-H "Content-type:application/json" \
-X PUT \
http://localhost:3000/api/admin/oauth-providers/github \
-d '{ "enabled": true, "id": "Iv1.abc123", "secret": "...", "loginStyle": "redirect" }'
```
Returns the same source report as `GET` - without the secret.
## Passwordless
| URL | Requires Auth (global admin) | HTTP Method |
| :--- | :--- | :--- |
| `/api/admin/passwordless` | `yes` | `PUT` |
```bash
curl -H "Authorization: Bearer t7iYB86mXoLfP_XsMegxF41oKT7iiA9lDYiKVtXcctl" \
-H "Content-type:application/json" \
-X PUT \
http://localhost:3000/api/admin/passwordless \
-d '{ "enabled": true }'
```
Result: `{ "passwordless": { "source": "admin", "value": true } }`.