You're viewing **Apigee Edge** documentation.  
[Go to the
**Apigee X** documentation](http://cloud.google.com/apigee/docs/reference/apis/apigee/rest). info

> [!WARNING]
> **Important:**When making HTTP requests, never send sensitive data, such as user credentials, in the request URI or in query parameters. You can use any compliant OAuth2 call to make Apigee API calls, but be aware that any sensitive data that appears in a URI or query parameter can be logged or seen by any service where TLS is not in place.

You can use the Edge OAuth2 service to exchange your credentials for an access and refresh token
that you then use to call Edge endpoints in your
[OAuth](https://docs.apigee.com/api-platform/system-administration/using-oauth2-security-apigee-edge-management-api) workflows.

In addition to the techniques described in this section, you can also use the
[acurl](https://docs.apigee.com/api-platform/system-administration/using-acurl) and
[`get_token`](https://docs.apigee.com/api-platform/system-administration/using-gettoken) utilities to get OAuth2 tokens.

### Path

```
POST https://login.apigee.com/oauth/token
```

If you are accessing the Edge OAuth2 service from a SAML-enabled org in Edge for Public Cloud, you
must include the zone name in your path. For example:

```
POST https://zone.login.apigee.com/oauth/token
```

### Request headers

| Parameter | Value |
|---|---|
| `Content-Type` | "application/x-www-form-urlencoded" |
| `Accept` | "application/json;charset=utf-8" |
| `Authorization` | "Basic ZWRnZWNsaTplZGdlY2xpc2VjcmV0" > [!NOTE] > ### NOTE > Use this value exactly as shown here. It is a hard-coded value that the API requires > in the Authorization header. You can export this value to an environment variable so that you can reuse it in these API calls. For example: ``` export CLIENT_AUTH=ZWRnZWNsaTplZGdlY2xpc2VjcmV0 ``` ``` curl ... -H "Authorization: Basic $CLIENT_AUTH" ... ``` |

### Form parameters

| Parameter | Required? | Value |
|---|---|---|
| `username` | **Optional. A username and password combination or a passcode is required.** | Your Apigee username, which is usually the email address associated with your Apigee account. |
| `password` | **Optional. A username and password combination or a passcode is required.** | The password for your Apigee account. |
| `mfa_token` | **Optional** | A valid multi-factor authentication (MFA) code for your account. Required only if you have [MFA enabled](https://docs.apigee.com/api-platform/system-administration/enable-two-factor-auth-your-apigee-account). |
| `passcode` | **Optional. A username and password combination or a passcode is required.** | A [one-time passcode](https://docs.apigee.com/api-platform/system-administration/auth-tools#passcode) you can use in place of a password. A passcode is required when authenticating with a SAML IDP, and may be used to authenticate with an LDAP IDP. |
| `grant_type` | **Required** | Determines whether you get a new access token or refresh the existing token. Valid values are: - "password": Get a new access token. When `grant_type` is "password", you must include your Apigee credentials in the request. - "refresh_token": Send a refresh token to get a new access token. When `grant_type` is "refresh_token", you are not required to include your credentials in the request. |
| `refresh_token` | Optional | The token you pass to get a new access token when the current access token has expired. This parameter is required when `grant_type` is "refresh_token". |

### Examples

> [!NOTE]
>
> #### NOTE
>
> The examples in this section use `curl` to make API requests. You should consider using `acurl`, Apigee's utility that acts as a convenience wrapper around `curl`. `acurl` passes in the access tokens and refreshes them for you when the tokens expire.

> [!WARNING]
> **Warning:** Be aware that sensitive data sent in an HTTP request can potentially be logged or seen by remote services if you are not careful. The best practice is to send sensitive data in a request body and never in headers or as part of a URI. Note that the following examples use the cURL option `-d`, which sends the data in the request body. Whichever language-specific mechanism you use to make requests, be sure that sensitive data is not exposed.

### Get a new access token

> To get a new access token, set the `grant_type` to "password":
>
> ```
> curl -H "Content-Type:application/x-www-form-urlencoded;charset=utf-8" \
>       -H "Accept: application/json;charset=utf-8" \
>       -H "Authorization: Basic ZWRnZWNsaTplZGdlY2xpc2VjcmV0" \
>       -X POST https://login.apigee.com/oauth/token \
>       -d 'username=ahamilton@example.com&password=mypassw0rd&grant_type=password'
> ```

### Get a new access token with MFA

> To get a new access token with MFA (multi-factor authentication) enabled,
> [get the MFA code](https://docs.apigee.com/api-platform/system-administration/enable-two-factor-auth-your-apigee-account#logginginwithtwofactorauth)
> and then set the `mfa_token` parameter to its value:
>
> ```
> curl -H "Content-Type:application/x-www-form-urlencoded;charset=utf-8" \
>   -H "Accept: application/json;charset=utf-8" \
>   -H "Authorization: Basic ZWRnZWNsaTplZGdlY2xpc2VjcmV0" \
>   -X POST https://login.apigee.com/oauth/token?mfa_token=424242 \
>   -d 'username=ahamilton@example.com&password=mypassw0rd&grant_type=password'
> ```

### Refresh an access token

> To refresh an access token, set `grant_type` to "refresh_token" and add your
> existing refresh token as a form parameter:
>
> ```
> curl -H "Content-Type:application/x-www-form-urlencoded;charset=utf-8"
>   -H "Accept: application/json;charset=utf-8" \
>   -H "Authorization: Basic ZWRnZWNsaTplZGdlY2xpc2VjcmV0" \
>   -X POST https://login.apigee.com/oauth/token \
>   -d 'grant_type=refresh_token&refresh_token=YOUR_REFRESH_TOKEN'
> ```
>
> Note that you do not need to pass your credentials when refreshing your access token.

### Responses

On success, you will get back an access token, refresh token, and related information. For
example:

```
{
  "access_token": "eyJhbGciOiJSUzI1NiJ9.eyJqdGkiOimYyD8IP2IyYS1jNmNiLTQ4NTgtYjZkMS1mZjkyNGFkYTk1YWUiLCJzdWIiOiI0X0KLSNjZlNjM0ZC0zZjlhLTRiNYmFjNi1kYjE2M2M5OGEzOGYiLCJzY29wZSI6WyJzYbmlkIiwicGFzc3dvcmQud3JpdGUiLCJhcHByb3ZhbHMubWUiLCJvYXV0aC5hcHByb3ZhbHMiXSwiY2xpZW50X2lkIjoiZWRnZWNsaSIsImNpZCI6ImVkZ2VjbGkiLCJhenAiOiJlZGdlY2xpIiwiZ3JhbnRfdHlwZSI6InBhc3N3b3JkIiwidXNlcl9pZCI6IjQ2NmU2MzRkLTNmOWEtNGI0MS1iYWM2LWRiMTYzYzk4YTM4ZiIsIm9yaWdpbiI6InVzZXJncmlkIiwidXNlcl9uYW1lIjoid3dpdG1hbkBhcGlnZWUuY29tIiwiZW1haWwiOiJ3d2l0bWFuQGFwaWdlZS5jb20iLCJhdXRoX3RpbWUiOjE0NzMyNjU4NzcsImFsIjoyLCJyZXZfc2lnIjoiZTc0ZGY0M2QiLCJpYXQiOjE0NzMyNjU4NzcsImV4cCI6MTQ3MzI2NzY3NywiaXNzIjoiaHR0cHM6Ly9sb2dpbi5hcGlnZWUuY29tL29hdXRoL3Rva2VuIiwiemlkIjoidWFhIiwi2ltLm1lIiwib3BlYXVkIjpbImVkZ2VjbGkiLCJzY2ltIiwib3BlbmlkIiwicGFzc3dvcmQiLCJhcHByb3ZhbHMiLCJvYXV0aCJdfQ.AFuevkeGGUGSPED8leyEKaT-xg1xk_VEiKJLEpipVvQBXIqEc9wqcpm-ZuoatA9DhjASRuFSRaHH8Fasx_vBxEBsUNhRY-GTMw7_8fv4yRMOb2AO3WUl_NWwPkC8XRSI1zCMbAZicojsJ1n3OSP487Mu9dl9ByX5A_QfHV2_cj4l9-SD7u6vOdfdbBxbNMAQkfZLrVIEU8myF2dhKnNeMiuoHSHANsQFcx0_BFA1HnSUnVi4RYj1FlTs9SbcPnS1d7t7eVdxWz_q2OFVXNIBMELAvvM0WhXPYTW3Osve3UvvUs6ekGs-K-RCPSok-4-NJbdCDpZQQTgqHsrf77NTsw",
  "token_type": "bearer",
  "refresh_token": "eyJhbGciOiJSUzI1NiJ9.eyJqdGkiOiJmZTIIMZWI0ZS00YzFmLTRjOTEtYmY5Mi1mMzZLEMzNjZhMDctciIsInN1YiI6IjQ2NmU2MzRkLTNmOWEtNGI0MS1iY17LLWRiMTYzYzk4YTM4ZiIsInNjb3BlIjpbInNjaW0ubWUiLCJvcGVuaWQiLCJwYXNzd29yZC53cml0ZSIsImFwcHJvdmFscy5tZSIsIm9hdXRoLmFwcHJvdmFscyJdLCJpYXQiOjE0NzMyNjU4NzcsImV4cCI6MTQ3NsaSIsImNsaWVudF9pZCI6ImVkZ2VjbGkiLCJpc3MiOiJodHRwczovL2xvZ2luLmFwaWdlZS5jb20vb2F1dGgvdG9rZW4iLCJ6aWQiOiJ1YWEiLCJncmFudF90eXBlIjoicGFzc3dvcmQiLCJ1c2VyX25hbWUiOiJ3d2l0bWFuQGFwaWdlZS5jbMzM1MDQ3NywiY2lkIjoiZWRnZW20iLCJvcmlnaW4iOiJ1c2VyZ3JpZCIsInVzZXJfaWQiOiI0NjZlNjM0ZC0zZjlhLTRiNDEtYmFjNi1kYjE2M2M5OGEzOGYiLCJhbCI6MiwicmV2X3NpZyI6ImU3NGRmNDNkIiwiYXVkIjpbImVkZ2VjbGkiLCJzY2ltIiwib3BlbmlkIiwicGFzc3dvcmQiLCJhcHByb3ZhbHMiLCJvYXV0aCJdfQ.kBP5AkbRS7Tnp-5VAfTLVfkUbUer4gFEU6A7g202KTKiXbqTwPSmOIGFTK12XevVPQYmAaSMFAnempWKfY7sjaY7HC7q3mGl53_A18cnkKhtNq15wCnyMom_bX_MYLW1RQPFytJ6akSJ-JkoPFU0x_FQg1JIvub1A8eqQxcR0KP-QRCxYAS4HTjH80vDIxHNt1tg7clmpa3RlHri0dlPVVsSpTXXhkpXRg5QbiWMrpkACSV22c0x0KiNu7vx5A520VOCO7hQ7IzmVIcSWcRqI97L7WdCjH_q4105bs2qmW73670MC0UGiJ9t5B1S1cxwqpUEd-NAuCsY8SVn6eWzbA",
  "expires_in": 1799,
  "scope": "scim.me openid password.write approvals.me oauth.approvals",
  "jti": "9bf2cb2a-c6cb-4858-b6d1-ff924ada95ae"
}
```

Save the response values:

- Use the `access_token` in calls to the Edge API
- Use the `refresh_token` when your access token expires and you need to refresh it

If you get a response like the following:

```
{
  "error": "unauthorized",
  "error_description": "Bad credentials"
}
```

Be sure that you used the exact string given above ("ZWRnZWNsaTplZGdlY2xpc2VjcmV0") for the
`Authorization` header in your request.