# Authentication

The Movemint API uses **OAuth 2.0** for authentication and authorization. All API entity requests require a valid **Bearer token**.

#### Supported Grant Types

| Grant Type         | Use Case                                                         |
| ------------------ | ---------------------------------------------------------------- |
| Authorization Code | Server-side applications that can securely store a client secret |
| Client Credentials | Machine-to-machine communication with no user context            |

#### Step 1: Register an OAuth Application

Contact the Movemint team to register your OAuth application. You will receive a **Client ID** (`client_id`) and **Client Secret** (`client_secret`). You must also provide one or more **Redirect URIs** where users will be sent after authorizing your application.

#### Step 2: Authorization Code Flow

Redirect the user's browser to the authorization endpoint:

```
GET https://www.movemint.cc/oauth/authorize
  ?client_id=YOUR_CLIENT_ID
  &redirect_uri=YOUR_REDIRECT_URI
  &response_type=code
  &scope=
```

After the user approves access, they are redirected back to your `redirect_uri` with an authorization `code` query parameter:

```
https://your-app.com/callback?code=AUTHORIZATION_CODE
```

#### Step 3: Exchange the Code for Tokens

```bash
curl -X POST https://www.movemint.cc/oauth/token \
  -d grant_type=authorization_code \
  -d code=AUTHORIZATION_CODE \
  -d client_id=YOUR_CLIENT_ID \
  -d client_secret=YOUR_CLIENT_SECRET \
  -d redirect_uri=YOUR_REDIRECT_URI
```

**Response:**

```json
{
  "access_token": "ACCESS_TOKEN",
  "token_type": "Bearer",
  "expires_in": 7200,
  "refresh_token": "REFRESH_TOKEN",
  "created_at": 1700000000
}
```

Access tokens expire after **2 hours** (7200 seconds) by default.

#### Step 4: Refresh an Expired Token

```bash
curl -X POST https://www.movemint.cc/oauth/token \
  -d grant_type=refresh_token \
  -d refresh_token=REFRESH_TOKEN \
  -d client_id=YOUR_CLIENT_ID \
  -d client_secret=YOUR_CLIENT_SECRET
```

#### Step 5: Use the Token in API Requests

Include the access token as a Bearer token in the `Authorization` header:

```bash
curl -H "Authorization: Bearer ACCESS_TOKEN" \
  https://www.movemint.cc/api/v1/me
```

#### Revoking Tokens

To revoke an access token or refresh token:

```bash
curl -X POST https://www.movemint.cc/oauth/revoke \
  -d token=TOKEN_TO_REVOKE \
  -d client_id=YOUR_CLIENT_ID \
  -d client_secret=YOUR_CLIENT_SECRET
```

## Obtain or refresh an access token

> Exchange an authorization code or refresh token for an access token.\
> This endpoint supports the \`authorization\_code\`, \`refresh\_token\`, and\
> \`client\_credentials\` grant types.<br>

````json
{"openapi":"3.1.0","info":{"title":"Movemint API","version":"1.0"},"tags":[{"name":"Authentication","description":"The Movemint API uses **OAuth 2.0** for authentication and authorization. All API entity requests require a valid **Bearer token**.\n\n### Supported Grant Types\n\n| Grant Type | Use Case |\n|------------|----------|\n| Authorization Code | Server-side applications that can securely store a client secret |\n| Client Credentials | Machine-to-machine communication with no user context |\n\n### Step 1: Register an OAuth Application\n\nContact the Movemint team to register your OAuth application. You will\nreceive a **Client ID** (`client_id`) and **Client Secret**\n(`client_secret`). You must also provide one or more **Redirect URIs**\nwhere users will be sent after authorizing your application.\n\n### Step 2: Authorization Code Flow\n\nRedirect the user's browser to the authorization endpoint:\n\n```\nGET https://www.movemint.cc/oauth/authorize\n  ?client_id=YOUR_CLIENT_ID\n  &redirect_uri=YOUR_REDIRECT_URI\n  &response_type=code\n  &scope=\n```\n\nAfter the user approves access, they are redirected back to your\n`redirect_uri` with an authorization `code` query parameter:\n\n```\nhttps://your-app.com/callback?code=AUTHORIZATION_CODE\n```\n\n### Step 3: Exchange the Code for Tokens\n\n```bash\ncurl -X POST https://www.movemint.cc/oauth/token \\\n  -d grant_type=authorization_code \\\n  -d code=AUTHORIZATION_CODE \\\n  -d client_id=YOUR_CLIENT_ID \\\n  -d client_secret=YOUR_CLIENT_SECRET \\\n  -d redirect_uri=YOUR_REDIRECT_URI\n```\n\n**Response:**\n\n```json\n{\n  \"access_token\": \"ACCESS_TOKEN\",\n  \"token_type\": \"Bearer\",\n  \"expires_in\": 7200,\n  \"refresh_token\": \"REFRESH_TOKEN\",\n  \"created_at\": 1700000000\n}\n```\n\nAccess tokens expire after **2 hours** (7200 seconds) by default.\n\n### Step 4: Refresh an Expired Token\n\n```bash\ncurl -X POST https://www.movemint.cc/oauth/token \\\n  -d grant_type=refresh_token \\\n  -d refresh_token=REFRESH_TOKEN \\\n  -d client_id=YOUR_CLIENT_ID \\\n  -d client_secret=YOUR_CLIENT_SECRET\n```\n\n### Step 5: Use the Token in API Requests\n\nInclude the access token as a Bearer token in the `Authorization` header:\n\n```bash\ncurl -H \"Authorization: Bearer ACCESS_TOKEN\" \\\n  https://www.movemint.cc/api/v1/me\n```\n\n### Revoking Tokens\n\nTo revoke an access token or refresh token:\n\n```bash\ncurl -X POST https://www.movemint.cc/oauth/revoke \\\n  -d token=TOKEN_TO_REVOKE \\\n  -d client_id=YOUR_CLIENT_ID \\\n  -d client_secret=YOUR_CLIENT_SECRET\n```\n"}],"servers":[{"url":"https://www.movemint.cc","description":"Production"}],"security":[],"paths":{"/oauth/token":{"post":{"tags":["Authentication"],"summary":"Obtain or refresh an access token","description":"Exchange an authorization code or refresh token for an access token.\nThis endpoint supports the `authorization_code`, `refresh_token`, and\n`client_credentials` grant types.\n","operationId":"createToken","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"oneOf":[{"$ref":"#/components/schemas/AuthorizationCodeGrantRequest"},{"$ref":"#/components/schemas/RefreshTokenGrantRequest"},{"$ref":"#/components/schemas/ClientCredentialsGrantRequest"}]}}}},"responses":{"200":{"description":"Token issued successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"400":{"description":"Invalid grant or request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"401":{"description":"Invalid client credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}}}}}},"components":{"schemas":{"AuthorizationCodeGrantRequest":{"type":"object","required":["grant_type","code","client_id","client_secret","redirect_uri"],"properties":{"grant_type":{"type":"string","enum":["authorization_code"]},"code":{"type":"string","description":"The authorization code received from the authorization endpoint"},"client_id":{"type":"string","description":"Your application's Client ID"},"client_secret":{"type":"string","description":"Your application's Client Secret"},"redirect_uri":{"type":"string","format":"uri","description":"The same redirect URI used in the authorization request"}}},"RefreshTokenGrantRequest":{"type":"object","required":["grant_type","refresh_token","client_id","client_secret"],"properties":{"grant_type":{"type":"string","enum":["refresh_token"]},"refresh_token":{"type":"string","description":"The refresh token issued alongside the access token"},"client_id":{"type":"string","description":"Your application's Client ID"},"client_secret":{"type":"string","description":"Your application's Client Secret"}}},"ClientCredentialsGrantRequest":{"type":"object","required":["grant_type","client_id","client_secret"],"properties":{"grant_type":{"type":"string","enum":["client_credentials"]},"client_id":{"type":"string","description":"Your application's Client ID"},"client_secret":{"type":"string","description":"Your application's Client Secret"}}},"TokenResponse":{"type":"object","required":["access_token","token_type","expires_in","created_at"],"properties":{"access_token":{"type":"string","description":"The access token to use in API requests"},"token_type":{"type":"string","enum":["Bearer"],"description":"Always \"Bearer\""},"expires_in":{"type":"integer","description":"Token lifetime in seconds (default 7200 = 2 hours)"},"refresh_token":{"type":"string","description":"Token used to obtain a new access token when the current one expires. Not present for client_credentials grants."},"created_at":{"type":"integer","description":"Unix timestamp of when the token was created"}}},"OAuthError":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Machine-readable error code"},"error_description":{"type":"string","description":"Human-readable description of the error"}}}}}}
````

## Revoke a token

> Revoke an access token or refresh token. After revocation, the token\
> can no longer be used to access protected resources.<br>

````json
{"openapi":"3.1.0","info":{"title":"Movemint API","version":"1.0"},"tags":[{"name":"Authentication","description":"The Movemint API uses **OAuth 2.0** for authentication and authorization. All API entity requests require a valid **Bearer token**.\n\n### Supported Grant Types\n\n| Grant Type | Use Case |\n|------------|----------|\n| Authorization Code | Server-side applications that can securely store a client secret |\n| Client Credentials | Machine-to-machine communication with no user context |\n\n### Step 1: Register an OAuth Application\n\nContact the Movemint team to register your OAuth application. You will\nreceive a **Client ID** (`client_id`) and **Client Secret**\n(`client_secret`). You must also provide one or more **Redirect URIs**\nwhere users will be sent after authorizing your application.\n\n### Step 2: Authorization Code Flow\n\nRedirect the user's browser to the authorization endpoint:\n\n```\nGET https://www.movemint.cc/oauth/authorize\n  ?client_id=YOUR_CLIENT_ID\n  &redirect_uri=YOUR_REDIRECT_URI\n  &response_type=code\n  &scope=\n```\n\nAfter the user approves access, they are redirected back to your\n`redirect_uri` with an authorization `code` query parameter:\n\n```\nhttps://your-app.com/callback?code=AUTHORIZATION_CODE\n```\n\n### Step 3: Exchange the Code for Tokens\n\n```bash\ncurl -X POST https://www.movemint.cc/oauth/token \\\n  -d grant_type=authorization_code \\\n  -d code=AUTHORIZATION_CODE \\\n  -d client_id=YOUR_CLIENT_ID \\\n  -d client_secret=YOUR_CLIENT_SECRET \\\n  -d redirect_uri=YOUR_REDIRECT_URI\n```\n\n**Response:**\n\n```json\n{\n  \"access_token\": \"ACCESS_TOKEN\",\n  \"token_type\": \"Bearer\",\n  \"expires_in\": 7200,\n  \"refresh_token\": \"REFRESH_TOKEN\",\n  \"created_at\": 1700000000\n}\n```\n\nAccess tokens expire after **2 hours** (7200 seconds) by default.\n\n### Step 4: Refresh an Expired Token\n\n```bash\ncurl -X POST https://www.movemint.cc/oauth/token \\\n  -d grant_type=refresh_token \\\n  -d refresh_token=REFRESH_TOKEN \\\n  -d client_id=YOUR_CLIENT_ID \\\n  -d client_secret=YOUR_CLIENT_SECRET\n```\n\n### Step 5: Use the Token in API Requests\n\nInclude the access token as a Bearer token in the `Authorization` header:\n\n```bash\ncurl -H \"Authorization: Bearer ACCESS_TOKEN\" \\\n  https://www.movemint.cc/api/v1/me\n```\n\n### Revoking Tokens\n\nTo revoke an access token or refresh token:\n\n```bash\ncurl -X POST https://www.movemint.cc/oauth/revoke \\\n  -d token=TOKEN_TO_REVOKE \\\n  -d client_id=YOUR_CLIENT_ID \\\n  -d client_secret=YOUR_CLIENT_SECRET\n```\n"}],"servers":[{"url":"https://www.movemint.cc","description":"Production"}],"security":[],"paths":{"/oauth/revoke":{"post":{"tags":["Authentication"],"summary":"Revoke a token","description":"Revoke an access token or refresh token. After revocation, the token\ncan no longer be used to access protected resources.\n","operationId":"revokeToken","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["token","client_id","client_secret"],"properties":{"token":{"type":"string","description":"The access token or refresh token to revoke"},"client_id":{"type":"string","description":"Your application's Client ID"},"client_secret":{"type":"string","description":"Your application's Client Secret"}}}}}},"responses":{"200":{"description":"Token revoked successfully (always returns 200, even if the token was already revoked)"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}}}}}},"components":{"schemas":{"OAuthError":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Machine-readable error code"},"error_description":{"type":"string","description":"Human-readable description of the error"}}}}}}
````

## Get token info

> Retrieve metadata about the current access token, including its\
> scopes, expiration, and associated resource owner and application.<br>

````json
{"openapi":"3.1.0","info":{"title":"Movemint API","version":"1.0"},"tags":[{"name":"Authentication","description":"The Movemint API uses **OAuth 2.0** for authentication and authorization. All API entity requests require a valid **Bearer token**.\n\n### Supported Grant Types\n\n| Grant Type | Use Case |\n|------------|----------|\n| Authorization Code | Server-side applications that can securely store a client secret |\n| Client Credentials | Machine-to-machine communication with no user context |\n\n### Step 1: Register an OAuth Application\n\nContact the Movemint team to register your OAuth application. You will\nreceive a **Client ID** (`client_id`) and **Client Secret**\n(`client_secret`). You must also provide one or more **Redirect URIs**\nwhere users will be sent after authorizing your application.\n\n### Step 2: Authorization Code Flow\n\nRedirect the user's browser to the authorization endpoint:\n\n```\nGET https://www.movemint.cc/oauth/authorize\n  ?client_id=YOUR_CLIENT_ID\n  &redirect_uri=YOUR_REDIRECT_URI\n  &response_type=code\n  &scope=\n```\n\nAfter the user approves access, they are redirected back to your\n`redirect_uri` with an authorization `code` query parameter:\n\n```\nhttps://your-app.com/callback?code=AUTHORIZATION_CODE\n```\n\n### Step 3: Exchange the Code for Tokens\n\n```bash\ncurl -X POST https://www.movemint.cc/oauth/token \\\n  -d grant_type=authorization_code \\\n  -d code=AUTHORIZATION_CODE \\\n  -d client_id=YOUR_CLIENT_ID \\\n  -d client_secret=YOUR_CLIENT_SECRET \\\n  -d redirect_uri=YOUR_REDIRECT_URI\n```\n\n**Response:**\n\n```json\n{\n  \"access_token\": \"ACCESS_TOKEN\",\n  \"token_type\": \"Bearer\",\n  \"expires_in\": 7200,\n  \"refresh_token\": \"REFRESH_TOKEN\",\n  \"created_at\": 1700000000\n}\n```\n\nAccess tokens expire after **2 hours** (7200 seconds) by default.\n\n### Step 4: Refresh an Expired Token\n\n```bash\ncurl -X POST https://www.movemint.cc/oauth/token \\\n  -d grant_type=refresh_token \\\n  -d refresh_token=REFRESH_TOKEN \\\n  -d client_id=YOUR_CLIENT_ID \\\n  -d client_secret=YOUR_CLIENT_SECRET\n```\n\n### Step 5: Use the Token in API Requests\n\nInclude the access token as a Bearer token in the `Authorization` header:\n\n```bash\ncurl -H \"Authorization: Bearer ACCESS_TOKEN\" \\\n  https://www.movemint.cc/api/v1/me\n```\n\n### Revoking Tokens\n\nTo revoke an access token or refresh token:\n\n```bash\ncurl -X POST https://www.movemint.cc/oauth/revoke \\\n  -d token=TOKEN_TO_REVOKE \\\n  -d client_id=YOUR_CLIENT_ID \\\n  -d client_secret=YOUR_CLIENT_SECRET\n```\n"}],"servers":[{"url":"https://www.movemint.cc","description":"Production"}],"security":[{"bearerAuth":[]},{"oauth2":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Pass the access token in the `Authorization` header:\n```\nAuthorization: Bearer YOUR_ACCESS_TOKEN\n```\n"},"oauth2":{"type":"oauth2","description":"OAuth 2.0 authentication using the Authorization Code or Client\nCredentials grant flow.\n","flows":{"authorizationCode":{"authorizationUrl":"https://www.movemint.cc/oauth/authorize","tokenUrl":"https://www.movemint.cc/oauth/token","refreshUrl":"https://www.movemint.cc/oauth/token","scopes":{}},"clientCredentials":{"tokenUrl":"https://www.movemint.cc/oauth/token","scopes":{}}}}},"schemas":{"TokenInfo":{"type":"object","required":["scopes","expires_in_seconds","application","created_at"],"properties":{"resource_owner_id":{"type":"integer","format":"int64","description":"The ID of the athlete who authorized the token"},"scopes":{"type":"array","items":{"type":"string"},"description":"List of scopes granted to this token"},"expires_in_seconds":{"type":"integer","description":"Seconds until the token expires"},"application":{"type":"object","properties":{"uid":{"type":"string","description":"The OAuth application's Client ID"}}},"created_at":{"type":"integer","description":"Unix timestamp of when the token was created"}}},"OAuthError":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Machine-readable error code"},"error_description":{"type":"string","description":"Human-readable description of the error"}}}}},"paths":{"/oauth/token/info":{"get":{"tags":["Authentication"],"summary":"Get token info","description":"Retrieve metadata about the current access token, including its\nscopes, expiration, and associated resource owner and application.\n","operationId":"getTokenInfo","responses":{"200":{"description":"Token information","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenInfo"}}}},"401":{"description":"Token is invalid or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}}}}}}}
````
