OAuth apps
Let other people connect their MockFlow account to your app, with the authorization code flow.
An API key acts as you. An OAuth app acts as whoever connects it: each person signs in to MockFlow, approves your app, and your app gets a token that works on their boards with the scopes they approved. Use an app when people other than you will connect, and a key from the developer console when the only account is yours.
URLs
Authorization URLGEThttps://mockflow.com/mcp-oauth/. Where the person signs in and approves your app.
Token URLPOSThttps://mockflow.com/mcp-oauth/token. Where your server exchanges the code, and later the refresh token, for tokens.
Revoke URLPOSThttps://mockflow.com/mcp-oauth/revoke. Where your server gives tokens back when someone disconnects your app.
API base URLhttps://api.mockflow.com/v1. Where your app calls the API with the access token.
Register an app
Open the OAuth apps tab of the developer console and register the app. You get a client ID, and for a server app a client secret starting mf_cs_. The console can reveal the secret again, rotate it, disable the app or delete it.
Fields
NamestringrequiredShown on the consent screen as "Connect *name*". Up to 200 characters.
DescriptionstringShown under the name on the consent screen. Up to 500 characters.
LogoimageShown beside MockFlow's logo on the consent screen. A square PNG, JPEG or WebP, up to 512 KB.
Redirect URIstringrequiredWhere MockFlow sends the person back with a code. One per app, https only, with http allowed for localhost and 127.0.0.1 while you develop. No #fragment.
ScopesstringrequiredThe scopes your app may ask for. A request for a scope outside this list is refused on the consent screen, and the consent screen shows the person exactly what the token will be allowed to do.
Cannot keep a secretbooleanTick it for an app that runs on someone's device, such as a desktop, mobile or command line app. It gets no secret and must authorise with PKCE: a request without a code_challenge is refused. This cannot be changed later.
Registering asks you to accept the MockFlow developer terms on behalf of whoever builds and ships the app.
A workspace can register up to 25 apps.
In development, then published
A new app is in development: you and the people in your workspace can connect it, so you can build and test it together. Anyone else who tries sees that the app is still in development. When it is ready, press Publish in the console and anyone with a MockFlow account can connect it.
Publishing needs what a stranger sees on the consent screen: a description, a logo and an https redirect on your own domain rather than localhost. It also asks you to accept the current Developer Terms.
Unpublish takes the app back into development and disconnects everyone outside your workspace at once. They can connect again after you publish it.
1. Send the person to MockFlow
Open the consent page in the browser. The console shows this URL ready made for each app.
GET https://mockflow.com/mcp-oauth/?response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=https%3A%2F%2Fyourapp.com%2Fcallback
&scope=user%3Aread%20boards%3Aread
&state=RANDOM_VALUE
&code_challenge=BASE64URL_SHA256_OF_VERIFIER
&code_challenge_method=S256
Query parameters
response_typestringrequiredAlways code.
client_idstringrequiredYour app's client ID.
redirect_uristringrequiredThe redirect URI you registered, exactly as registered: no extra path, query or trailing slash.
scopestringSpace separated scopes, from the ones you registered. Leave it out for all of them. A scope you did not register is refused, not dropped.
statestringA random value you keep in the person's session. It comes back unchanged; refuse the callback when it does not match.
code_challengestringThe base64url SHA-256 of a random code_verifier of 43 to 128 characters. Required for an app registered as unable to keep a secret, and worth sending from every app.
code_challenge_methodstringS256, the only method supported.
Someone who is not signed in can sign in on the same page, with Google, Microsoft or their email. They then see your app's name and description, and choose Authorize or Deny.
2. Receive the code
On approval MockFlow redirects to your redirect URI with a code and your state.
https://yourapp.com/callback?code=AUTHORIZATION_CODE&state=RANDOM_VALUE
When the person denies, the redirect carries error=access_denied instead, with your state. Any other problem, such as an unknown client ID or a redirect URI that does not match, is shown on the consent page and is not sent back to your app.
3. Exchange the code for tokens
Make a POST request to https://mockflow.com/mcp-oauth/token from your server, with the Content-Type: application/x-www-form-urlencoded header. The client ID and secret go in the body, or in an HTTP Basic Authorization header; JSON bodies are not read. The code only works for the client it was issued to, and an app that has a secret must send it.
The code expires 10 minutes after it is issued and works once. Exchange it as soon as the person lands on your redirect URI.
curl -X POST https://mockflow.com/mcp-oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d grant_type=authorization_code \
-d code=AUTHORIZATION_CODE \
-d redirect_uri=https://yourapp.com/callback \
-d client_id=YOUR_CLIENT_ID \
-d client_secret=YOUR_CLIENT_SECRET \
-d code_verifier=YOUR_CODE_VERIFIER
Form fields
grant_typestringrequiredauthorization_code.
codestringrequiredThe code from the redirect.
redirect_uristringrequiredThe same redirect URI you sent in step 1.
client_idstringrequiredYour app's client ID.
client_secretstringYour app's secret. Required for every app that has one; an app without one proves itself with code_verifier.
code_verifierstringThe verifier behind the code_challenge, when you sent one.
{
"access_token": "4f9c\u2026",
"refresh_token": "a71e\u2026",
"token_type": "Bearer",
"expires_in": 86400,
"scope": "user:read boards:read"
}
4. Call the API
Send the access token as a bearer token, exactly like an API key. The call acts as the person who approved your app, in their workspace, and can only reach the boards they can open.
curl https://api.mockflow.com/v1/me \
-H "Authorization: Bearer ACCESS_TOKEN"
A missing, expired or revoked token answers 401. A token without the scope an operation needs answers 403; each operation's page lists its scope.
5. Refresh the token
Access tokens last 24 hours and refresh tokens 30 days. Before the access token runs out, trade the refresh token for a new pair.
curl -X POST https://mockflow.com/mcp-oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d grant_type=refresh_token \
-d refresh_token=REFRESH_TOKEN \
-d client_id=YOUR_CLIENT_ID \
-d client_secret=YOUR_CLIENT_SECRET
A refresh returns a new refresh token as well, and the old one stops working. Store both new tokens every time. After 30 days without a refresh, the person connects again.
6. Disconnect
When someone disconnects your app, deletes their account with you, or asks you to delete their data, give their tokens back. Post either the access token or the refresh token: both stop working at once, because they are one connection.
curl -X POST https://mockflow.com/mcp-oauth/revoke \
-H "Content-Type: application/x-www-form-urlencoded" \
-d token=REFRESH_TOKEN \
-d client_id=YOUR_CLIENT_ID \
-d client_secret=YOUR_CLIENT_SECRET
Form fields
tokenstringrequiredThe access token or the refresh token to revoke.
token_type_hintstringaccess_token or refresh_token. Accepted for compatibility; MockFlow finds the token either way.
client_idstringrequiredYour app's client ID.
client_secretstringYour app's secret, for an app that has one.
The answer is 200 with an empty object, whether or not the token was still valid, as RFC 7009 asks. A wrong secret answers 401 invalid_client. Delete your copy of the tokens either way.
Token endpoint errors
Failures answer with {"error": …, "error_description": …}, the OAuth 2.0 shape, rather than the API's error envelope.
Codes
invalid_requestA required field is missing.
unsupported_grant_typeOnly authorization_code and refresh_token are supported.
invalid_clientThe client is unknown or disabled, or its secret is missing or wrong.
invalid_grantThe code or refresh token is unknown, used or expired, belongs to another client, the redirect URI differs from step 1, or the code verifier does not match the challenge.
server_errorSomething failed on our side. Try again.
Ending access
Deleting or disabling an app in the console ends every token it holds at once, and a disabled app cannot be authorised again until you enable it. Rotating the secret leaves existing tokens working, so do it whenever the secret may have been seen.
People can also disconnect your app themselves, under Connected apps in their MockFlow account settings. From then on their tokens answer 401, and the next refresh fails with invalid_grant. Treat either as the person having disconnected.
Keep the client secret and the tokens on your server. An app that ships to people's devices should be registered as one that cannot keep a secret, and use PKCE.