---
title: "Passport & VPPA Integration (PBS Stations Only)"
canonical: "https://docs.pbs.org/space/PMSSO/50921521/Passport%20%26%20VPPA%20Integration%20(PBS%20Stations%20Only)"
format: markdown
---
> Macro (toc)

## Overview

This page provides guidance to stations on how to implement Passport and VPPA on their station site. 

## Authorization Flow

![integration_diagram (1).png](media://ea22b47d-8c80-45e6-9c57-eefb728ea727)

## User Workflow

- The user clicks login/register.
- The Identity Provider returns the token information
- The client stores the token information and calls the Profile Services* /login_resolve/* endpoint using the Access Token and Application ID.​
  - PBS will create a user Profile if it doesn’t already exist.
- Profile Services returns:
  - show_vppa_screen: true/false
  - Vppa_redirect URL
- The client calls the Profile Services /user/profile/ endpoint using the Access Token and Application ID. ​
- Profile Service returns:
  - PID (PBS Profile ID)
  - Profile Information (name, email, provider, vppa_accepted, vppa_last updated, etc.)

## Endpoints

### POST /v2/login_resolve/

This endpoint handles PBS specific logic after login with identity provider:

1. Sync account from IP into profile service.
2. Handle VPPA check and flow:

Current VPPA check algorithm implementation:

```
1. show_vppa_screen = unknown;
2. is_member = ask mvault about membership status
3. (is_member=False) and (activation_flow=False) -> show_vppa_screen=False; END_CHECK
4. vppa_accepted, vppa_last_updated = ask profile service about vppa status
5. vppa_accepted=null -> show_vppa_screen=True; END_CHECK
6. vppa_updated is not expired (has a value newer than 2 years ago) -> show_vppa_screen=False; END_CHECK
7. show_vppa_screen=True END_CHECK
```

## Request Parameters

Headers:

Authorization: <token_received_from_identity_provider_for_the_user_login>

The token is a valid token issued by the identity provider upon user sign in. The token pertains only to one user for which the login is resolved.

Application-Id: <PBS provided Profile Services application id>

The Application-Id header specifies the registered application id.  After this, a set of redirect urls can be whitelisted from the profile service admin.

Content-Type: application/x-www-form-urlencoded

You’d need to pass this Content-Type when sending any of the fields below in the request payload.

## Fields

| **Field** | **Definition** |
| --- | --- |
| handle_ux | Specifies if the User Experience should be handled server side. if this is enabled, the vppa acceptance screen can be served server side if the application redirects the user agent to the specified “vppa_redirect” uri. |
| return_uri | If handle_ux is requested, this parameter specifies a return uri to redirect back to after the vppa flow is finished such that the web app or mobile app can get back control of the flow. The redirect uri is checked against the whitelisted redirect urls defined for the application in the profile service admin. See more details above. |
| activation | Specifies if this is a passport activation flow which will force vppa checks independent of the user membership status. |
| station | Can be used to specify the station id in order to replace the pbs logo on the vppa screens with the station logo; this is only valid for the server side UX experience. |

## Response Structure

The response structure depends on whether the application specifies it wants the server to process the UX experience or not. If the application wants the server to handle the UX, it must specify a return url that the server will redirect the user agent upon vppa flow end.

1. The UX experience is handled inside the application (no handle_ux parameter present in the request). In this scenarios the app has to implement the vppa flow by replicating the associated screens and vppa check logic, as well as updating the user profile after he/she accepts or denied the agreement.

```
HTTP 200 OK

{

‘show_vppa_screen’: false #the app does not need to trigger the VPPA flow for this user

}
```

**OR**

```
HTTP 200 OK

{

‘show_vppa_screen’: true #the app needs to trigger the VPPA flow for this user

}
```

1. If the UX experience is handled by the server (handle_ux parameter present in the request) the server will use the return url provided by the application to return back to the site or application upon vppa flow end.

```
HTTP 200

{

‘show_vppa_screen’: true, # the app will redirect the user agent to the below url to start the vppa flow

‘vppa_redirect’: “http://localhost:8080/v2/vppa/?state=0kKTYqmQk0aUoJW8m1fxpOc3GUV…”

} # after the flow ends the server will redirect the user agent to the return_uri specified in # the request. The above state variable is a must and cannot be altered. Also, it is # limited in lifetime for security reasons.
```

1. If the UX experience is handled by the server (handle_ux parameter present in the request) but the user is not required to go through the vppa flow because he is not a member or has already accepted the vppa the server will just return show_vppa_screen set to False and provide no vppa_redirect in the response. In this case the app can just go along with its regular business flow.

```
HTTP 200 OK

{

‘show_vppa_screen’: false #the app does not need to trigger the VPPA flow for this user

}
```

## Responses

| HTTP Status Code | Error Code Description |
| --- | --- |
| 200 | The operation was successful. |
| 400 | Invalid request, for example app requested server side handling of the ux experience but provided no return url. |
| 403 | Forbidden. The user token is invalid or other security criteria are not met, such as invalid Application Id, invalid redirect_uri etc. |

Request-Response Sample

```
POST /v2/login_resolve/
Authorization: SvaHGdi2m7ahMAoDVaZHfr8thb3eA4
Application-Id: {PBS provided App ID}
 
 
HTTP/1.1 200 OK
{
    "show_vppa_screen": true
}
```

Request-Response Sample

```
POST /v2/login_resolve/
Content-Type: application/x-www-form-urlencoded
Authorization: SvaHGdi2m7ahMAoDVaZHfr8thb3eA4
Application-Id: {PBS provided App ID}

Form:
handle_ux=true
return_uri=http://localhost
station=7387eb2c-e0ce-4069-82d9-08865df87edf
 
{
    "show_vppa_screen": true,
    "vppa_redirect": "http://localhost:8080/v2/vppa/?state=0kKTYqmQk0aUoJW8m1fxpOc3GUV..."
}
 
The application should now redirect the user agent to the above url.
After vppa flow ends control will be handed back to the application by redirecting
the user agent to the return_uri.
```

Request-Response Sample

```
POST /v2/login_resolve/
Content-Type: application/x-www-form-urlencoded
Authorization: SvaHGdi2m7ahMAoDVaZHfr8thb3eA4
Application-Id: {PBS provided App ID}
 
Form:
handle_ux=true
return_uri=http://localhost
activation=true
 
{
    "show_vppa_screen": true,
    "vppa_redirect": "http://localhost:8080/v2/vppa/?state=0kKTYqmQk0aUoJW8m1fxpOc3GUV..."
}
 
This can be used in activation scenarios to force the vppa check independent of user
membership status. In this case, the user vppa acceptance is checked in profile service
and if he has not accepted any vppa the above response will be served.
```

### GET /v2/user/profile/

This endpoint retrieves user profile information based on the token present in the authorization header. The token is used to retrieve the aic_sub from Akamai for the user bearing the token. The sub is used to lookup the corresponding profile stored in profile service and retrieve the standard information attributes corresponding to the profile.

Headers:

Authorization: <token_received_from_identity_provider_for_the_user_login>

Application-Id: <PBS provided Profile Services application ID>

Request Parameters: None

Response Structure:

| Key | Type | Description |
| --- | --- | --- |
| status | Integer | The exit code of the operation. |
| description | String | The description of the exit code. |
| profile | Dict | The requested data, which has this structure: `{"first_name": "FName", "last_name": "LName", "thumbnail_url": "url_to_user_photo", "provider": "PBS", "birth_date": "1900-03-15", "email": "user@email.com", "login_providers": ["PBS"], "vppa_last_updated": "2016-02-10 14:00:52.781991+00:00", "vppa_accepted": true}, "pid": "1b695b4b-48e9-4dd7-b459-795ac41df9aa"` |

Response Codes:

| HTTP Status Code | Status | Description |
| --- | --- | --- |
| 200 | 200 | success |
| 403 | N/A | N/A |
| 404 | 404 | not found |

Request Sample:

```
GET /v2/user/profile/
Host: {PBS provided host domain}
Authorization: <token_from_identity_provider>
Application-Id: {PBS provided App ID}
```

Response Sample:

```
HTTP 200 OK
Content-Type: application/json
 
{"status": 200, "description": "success", "profile": {"first_name": "FName", "last_name": "LName", "thumbnail_url": "url_to_user_photo", "provider": "PBS", "birth_date": "1900-03-15", "email": "user@email.com", "login_providers": ["PBS"], "vppa_last_updated": "2016-02-10 14:00:52.781991+00:00", "vppa_accepted": true, "pid": "1b695b4b-48e9-4dd7-b459-795ac41df9aa"}
```

Response Sample:

```
HTTP 404 Not Found
Content-Type: application/json
 
{"status": 404, "description": "not found"}
```

Response Sample:

```
HTTP 403 Forbidden
```

### PATCH /v2/user/profile/

> 📝 **PBS does not recommend using the PATCH method to update the VPPA status. Please make sure to discuss any custom VPPA implementations with PBS before implementing them.**

This endpoint updates the vppa_status with the given value for a profile.

Headers:

Authorization: <token_received_from_identity_provider_for_the_user_login>

Application-Id: <PBS provided Profile Service application ID>

Content-Type: application/json

Request Parameters:

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| vppa_accepted | Boolean | Yes | The new vppa status value (True or False) |

Response Structure:

| Key | Type | Presence | Description |
| --- | --- | --- | --- |
| *errorCode* | Integer | Always | The exit code of the operation. |
| *errorMessage* | String | Always | The description of the exit code. |

Response Codes:

| HTTP Status Code | Error Code | Error Description |
| --- | --- | --- |
| 200 | 0 | The operation was successful |
| 400 | 400009 | Invalid value for vppa_accepted |
| 403 | N/A | Forbidden - this most likely means the access_token used has expired and needs to be refreshed by the app using the refresh token. |
| 404 | 404006 | Profile does not exist |

Request sample:

```
PATCH /v2/user/profile/
Host: {PBS provided Host domain}
Authorization: Bearer UP0z2TYFD6qPCWPfjNYqBzYq29WSHzvKfwo8hiArk19OLpJ843gURExX94xQp94G
Application-Id: {PBS provided App ID}
Content-Type: application/json
 
{"vppa_accepted": true}
```

Response sample:

```
HTTP 200 OK
Content-Type: application/json
 
{"errorCode": 200, "errorMessage": "The operation was successful"}
```

Profile not found:

```
HTTP 404 Not Found
Content-Type: application/json
 
{"errorCode": 404, "errorMessage": "Profile does not exist"}
```

Expired access_token error response sample:

```
HTTP 403 Forbidden
Content-Type: application/json
 
{"errorCode": 403, "errorMessage": "Forbidden"}
```