Authentication

Learn about Mural's OAuth 2.0 authentication flow.

The Mural API uses OAuth 2.0 as a secure method of authorizing interaction between your app and the Mural API. OAuth 2.0 requires that any app's access token request goes through an authentication process with the OAuth provider for extra security. Our current implementation of OAuth 2.0 uses the Authorization Code Grant method.

Also, we support PKCE (Proof Key for Code Exchange) to prevent malicious third parties from attempting to steal your access token.

📘

To see OAuth in use, download the sample app for OAuth flow.

How OAuth 2.0 works

For the Mural API, here’s how the OAuth 2.0 process works for a new user:

  1. When a user accesses your app, you need to redirect them to app.mural.co, the OAuth 2.0 provider. (This approach varies by implementation, but is often a redirect link.)
  2. The user authenticates and authorizes your app at app.mural.co, and gets redirected back to your app with an authorization code.
  3. Next, you’ll request an access token for the user with that authorization code.

Once a user is authenticated, here’s how the process works:

  1. Your app checks to see if there’s a valid access token.
  2. When the access token expires, you’ll use the refresh token to request a new access token by making a POST request to the Refresh Token URL.
  3. The Refresh Token URL responds with a new access token and new refresh token.

To learn more about the specifics of OAuth 2.0, see OAuth 2.0 Authorization Framework.

Set up OAuth 2.0 in Mural

If you’re integrating OAuth 2.0 into an app, you can set up and use an OAuth library in your language of choice. If you simply want to test the API and see how it works, we recommend using Postman or similar.

Here are the OAuth endpoints that we’ll reference in the next steps:

  • Authorization URL: https://app.mural.co/api/public/v1/authorization/oauth2/
  • Access Token URL: https://app.mural.co/api/public/v1/authorization/oauth2/token
  • Refresh Token URL: https://app.mural.co/api/public/v1/authorization/oauth2/token

Prerequisites

  • Create and log into your Mural account.
  • Register your app with Mural. Make sure to save your client ID, client secret, redirect URL(s), and scopes. Each time you request an access token, both the client secret and an authorization request are required. (Always keep your client secret to yourself. Do not share it with anyone.)

Authenticate users: Authorization Request

To authenticate a new user, your app must redirect them to app.mural.co with specific identifying information. (One common approach is to have a redirect link.) You’ll redirect the user via their browser with a GET method.

Use this GET method for a user redirect:

GET https://app.mural.co/api/public/v1/authorization/oauth2/? 
  client_id=:client_id&
  redirect_uri=:callback&
  scope=:scope&
  state=:state&
  response_type=code

Here’s a breakdown of the required parameters in the Authorization Request:

ParameterDescription
client_idThe client identifier for your app. You received this and a client secret when you created your app in Mural.
redirect_uriIf the user allows access to your app, the auth page will call this URI.

Note: This must be one of the values you set as your Redirect URLs when you created your app.
scopeMural's scopes have a resource type and a read or write permission. For example, a scope of room:read means the token permits read-only access to room data.

Note: The value of the scope parameter is expressed as a list of space-delimited, case-sensitive strings. E.g., room:read room:write.

To learn more about Mural's scopes, see Scopes.
stateA value that you randomly generate and store. (This is optional, but recommended.)
response_typeWe currently use the authorization code flow, so the value here is code.

After the user accesses the above URL, they are taken to Mural’s authentication page. Once they allow access, they are redirected to the Redirect URI specified as the redirect_uri in the authorization request.

For example, if the provided redirect URI was https://cleverexample.com/oauth/callback, then here’s how the expected callback request would look: https://cleverexample.com/oauth/callback?code=:code&state=:state

Here’s a breakdown of the parameters in the callback request:

ParameterDescription
codeThe authentication code that can be traded for an access token.
stateIf applicable, the state variable that was in the initial URL given to the user.

Authenticate users: Access Token Request

Next up, the authorization code needs to be passed back to OAuth’s API to get the user’s access token. You make a POST request:

Request:

POST 'https://app.mural.co/api/public/v1/authorization/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=my_client_id' \
--data-urlencode 'client_secret=my_client_secret' \
--data-urlencode 'redirect_uri=my_callback' \
--data-urlencode 'code=my_code' \
--data-urlencode 'grant_type=authorization_code'

Response:

{
  "access_token": <TOKEN>,
  "expires_in": <EXPIRATION (in seconds)>,
  "refresh_token": <REFRESH TOKEN>
}

Here’s a breakdown of the parameters in the Access Token Request:

ParameterDescription
client_idThe client identifier for your app. You received this and a client secret when you created your app in Mural.
client_secretThe secret key you copied when you created your app in Mural.
redirect_uriInclude if you used this parameter in the authorization request. Their values must be identical.
codeThe authorization code received from the authorization server.
grant_typeThe value must be authorization_code.

If the parameters match, you’ll receive a JSON response with the user access token and token expiration.

Use the OAuth Token

Once you have the user access token, you call the API, passing a Bearer authorization header. Here’s an example of how to use it:

curl -sH 'Authorization: Bearer <ACCESS_TOKEN>'
    'https://app.mural.co/api/public/v1/workspaces'

Refresh Token Request

By default, OAuth tokens expire after 15 minutes, so you’ll likely need to refresh your stored tokens. You do this using refresh_token and the following endpoint: https://app.mural.co/api/public/v1/authorization/oauth2/token

You can reuse your refresh_token as many times as you need to get a new access_token. You’ll do a POST request to refresh the token. Here’s how that looks:

Request:

POST 'https://app.mural.co/api/public/v1/authorization/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=my_client_id' \
--data-urlencode 'client_secret=my_client_secret' \
--data-urlencode 'refresh_token=my_refresh_token' \
--data-urlencode 'grant_type=refresh_token'

Response:

{
  "access_token": <TOKEN>,
  "expires_in": <EXPIRATION (in seconds)>
}

Here’s a breakdown of the parameters in the Refresh Token Request:

ParameterDescription
client_idThe client identifier for your app. You received this and a client secret when you created your app in Mural.
client_secretThe secret key you copied when you created your app in Mural.
refresh_tokenThe refresh token issued by the authorization server.
grant_typeThe value must be refresh_token.

Common Authorization Token Request errors

There are several things that can go wrong during the authorization token request step. Here are a few of the more common ones:

Invalid Request

If the request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed, you will receive the following error:

{
 "error": "invalid_request",
 "error_description": "The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed."
}

Incorrect Client Credentials

If your client credentials are invalid (client_id or client_secret), client authentication failed, you will receive the following error:

{
 "error": "invalid_client",
 "error_description": "Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method."
}

Redirect URI Mismatch or Invalid Grant

If the provided authorization grant (code) or refresh token is invalid, already used, expired, revoked, does not match the redirect_uri used in the authorization request, or was issued to another client, you will receive the following error:

{
 "error": "invalid_grant",
 "error_description": "The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client."
}

Unsupported Grant Type

If the authorization grant type is not supported by the authorization server, you will receive the following error:

{
 "error": "unsupported_grant_type",
 "error_description": "The authorization grant type is not supported."
}