Skip to main content

Plug And Charge API 1.0.1

Getting Started with Plug and Charge

Shell Plug and Charge API's are based on the "Open Plug&Charge Protocol" (OPCP) to support implementing ISO-15118-2. The intended audience for these API's are OEMs, CPOs and MSPs.

/v1/events is providing a simpler, cheaper and more safe alternative API instead of the WebHook API.

This API product consists of the following end points:

API End Point API Functionality
GET /v1/events Get events about created or revoked contracts.
GET /v1/oem/provCerts/lookupVehicle/{pcid} Check if a contract can be created for a certain PCID.
PUT /v1/cps/generate/signedContractData Generate or update the contract.
POST /v1/ccp/signedContractData Return an ISO-15118-2 CertificateInstallationRes based on the provided CertificateInstallationReq.
DELETE /v1/ccp/signedContractData/{emaid} Delete and revoke the contract for the provided EMAID.

Authentication

Shell API’s are secured by OAuth 2.0. It uses the 'Client Credentials' Grant Type to allow the API consumer to access data. The end to end process is illustrated in the sequence diagram below.

sequenceDiagram participant Partner participant Shell autonumber alt Manual Process rect rgb(200, 150, 255) Partner ->> Shell: Request Client ID and Client Secret activate Shell Shell ->> Partner : Generate and provide Client ID and Client Secret deactivate Shell end end alt Authentication/Authorization rect rgb(191, 223, 255) Partner->> Shell: Initiate request to OAuth end point with credentials activate Shell Shell ->> Partner : (200-OK) Returns Bearer Token deactivate Shell end end alt Call Functional Endpoint rect rgb(200, 150, 255) Partner ->> Shell: Initiate request to functional endpoint along with bearer token received from previous step activate Shell Shell ->> Partner: Returns a response on validation of the bearer token deactivate Shell end end

Requesting credentials (manual)

The partner requests a client id and client secret for use with their application. Shell's contact will provide these credentials to the partner.

The partner configures the application to use OAuth2. It will use the 'Client Credentials' Grant Type.

On the Shell side we also need to configure a role with claims for that client id.

Requesting a JWT token (app)

Paramaters

Once you receive the client ID & Secret, next step is to call the https://api-test.shell.com/v2/oauth/token endpoint to authenticate. Following are the key parameters-

Name Value
Method POST
Authorization Type OAuth 2.0
Auth URI https://api-test.shell.com/v2/oauth/token
Client_Id **** (OAuth Client ID)
Client Secret **** (OAuth Client Secret)
Grant Type client_credentials

Example

curl --location --request POST ' https://api-test.shell.com/v2/oauth/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=***********' \
--data-urlencode 'client_secret=*************' \
--data-urlencode 'grant_type=client_credentials'

Response

{
    "access_token": "***********",
    "token_type": "Bearer",
    "expires_in": 899
}

The response will contain the following parameters:

  • access_token: The token to be used to call the functional APIs
  • expires_in: The amount of seconds until the access token expires.
  • token_type: Bearer

Exception Handling

All error scenarios are returned with a response body and identifier.

{
    "Error": "401",
    "message": "Authorization value is incorrect to process the request."
}
HTTP Code Description
400 Bad Request If Invalid scope passed to Token url
Invalid grant type passed to Token url
401 Unauthorized If Invalid id/secret passed to Token url
If Invalid or expired token passed to destination system’s API

General

Request headers

All subsequent requests must include the following headers:

Header Description
Authorization Authorization header with a bearer token retrieved via the earlier described process. Example: Bearer ABCD1234
RequestId A unique request id. This needs to be a valid GUID. Example: 65c321e5-1051-4013-ac7f-6f2f5eab819d

Error messages

Error status codes will return the following response structure:

{
  "RequestId": "94b93c2e-3cd4-4dad-9ce4-2fff773b0bb7",
  "Status": "FAILED",
  "Errors": [
    {
      "Title": "Validation Error",
      "Code": "E0001",
      "Detail": "EMAID is missing",
      "AdditionalInfo": {}
    }
  ]
}

Status messages

The subscriptionUrl provided when generating or updating contract data will receive status messages. The same url will be used when the contract is revoked.

{
    "requestId": "f5a06ba6-cd69-4ddc-b0eb-ef9d6603d459",
    "operation": "CREATE_OR_UPDATE_CONTRACT_BUNDLE",
    "ids": [
        {
            "type": "EMAID",
            "value": "UKXXXC123456785"
        }
    ],
    "subStatuses": [
        {
            "scope": "GetContract",
            "status": "SUCCESS",
            "message": ""
        },
        {
            "scope": "GenerateStoreSignedContractBundleInCcp",
            "status": "PENDING",
            "message": ""
        }
    ],
    "status": "PENDING"
}

The message format currently deviates from what OPCP describes.

The status field contains the current status of the message. The field subStatuses shows a list of the statuses per sub system we are communicating with.

The following status codes are possible:

Code Meaning
PENDING An operation is pending
FAILED An operation failed
SKIPPED An operation is skipped
TIMEOUT An operation timed out
SUCCESS An operation is successful
UNKNOWN An operation status is unknown

The status field will be rendered from all subStatuses. The algorithm used is:

  1. If there are no subStatuses or all subStatuses are either "SKIPPED" or "UNKNOWN", the status is set to "SUCCESS".
  2. If all subStatuses, not considering "SKIPPED" or "UNKNOWN", have a "SUCCESS" status, then the status is set to "SUCCESS".
  3. If any of the subStatuses have a "FAILED" status, the status is set to "FAILED".
  4. If any of the subStatuses have a "TIMEOUT" status, and none have a "FAILED" status, the status is set to "TIMEOUT".
  5. If none of the above conditions are met, the status is set to "PENDING".

Get events about created or revoked contracts

Introduction

This is a long polling API. This means the when there are no events yet, this request will keep the connection open for 2 minutes, after that an empty result will be given.

Handle the requests as follows:

sequenceDiagram participant Client participant API loop Client->>Client: Load stored URL Client->>API: GET <URL> alt 200 Ok API-->>Client: Response (max 10 items) Note right of Client: Process response Client->>Client: Store Links.Next URL else Invalid API-->>Client: Invalid response or network issues Note right of Client: Delay for at least 1 minute end end

A normal response will always return a link to the next result set. Repeat this in a loop to process all events. Make sure to persist the Links.Next URL somewhere since this needs to be persistent among application restarts.

The returned result set is limited to 10 items. Retrieve further data by requesting data from the Links.Next URL.

In case no body is received with a Links.Next property, then the operation should be delayed for 1 minute or more and then tried again. If the HTTP STATUS code is 400 Bad Request then the input is incorrect, and it can be assumed that the subsequent request will also return 400 Bad Request.

This API returns only events you are allowed to receive based on your identities roles and claims.

To start this process we need to configure an initial URL. We have a few options:

Endpoint Description
/v1/events Start processing from the first stored event
/v1/events?fromDate=2023-01-01T00:00:00Z Start processing past the provided date
/v1/events?fromOffset=12 Start processing past the provided event id

This keeps the control at the Partner to reprocess events in case the need arises. Also, connection issues will never be a reason to lose events.

Parameters

Name Example Description
Method GET Request method
Authorization (Header) Bearer ABCD1234 Bearer token
RequestId (Header) db22ec42-f051-452a-af12-3bfcf17c0cdb GUID that identifies this request
fromDate (Query) 2023-01-01T00:00:00Z Start processing past the provided date
fromOffset (Query) 12 Start processing past the provided event identifier
eventTypes (Query) ContractCreated,ContractRevoked Filter the event types we want to receive

Filtering

By default all event types are returned. Currently we support only two event types:

Event Description
ContractCreated A new contract is created
ContractRevoked A contract is revoked

To apply this filter, add the following to the query:

  • GET /v1/events?fromOffset=12&eventTypes=ContractCreated,ContractRevoked
  • GET /v1/events?fromOffset=12&eventTypes=ContractCreated

The Links.Next URL will maintain the applied filters.

Request

curl --max-time 150 --location 'https://api-test.shell.com/ev/plugandcharge/EU-QA/v1/events' \
--header 'RequestId: de878377-79fc-4174-8184-10e2741f27af' \
--header 'Authorization: Bearer ABCD123'

Response

{
    "Data": [
        {
            "Id": 61,
            "Timestamp": "2023-09-19T14:30:11.581696Z",
            "Type": "ContractCreated",
            "Payload": {
                "pcid": "PCID",
                "emaid": "EMAID",
                "timestamp": "2023-09-19T14:30:11.389697+00:00",
                "dhPublicKey": "BASE64 ENCODED DH PUBLICKEY",
                "contractCert": "BASE64 ENCODED CONTRACT X509 CERT",
                "moSub1CaCert": "BASE64 ENCODED MO SUB CA1 X509 CERT",
                "moSub2CaCert": "BASE64 ENCODED MO SUB CA2 X509 CERT",
                "changeTimestamp": "2023-09-19T14:30:11.389697+00:00",
                "moRootSerialNumber": "aa:bb:cc:dd:ee:ff:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee",
                "vehicleCertificate": {
                    "wmi": "WMI",
                    "pcid": "PCID",
                    "timestamp": "2023-09-19T12:17:39.811648+00:00",
                    "oemProvCert": "BASE64 ENCODED OEM PROV X509 CERT",
                    "oemSub1CaCert": "BASE64 ENCODED OEM SUB CA1 X509 CERT",
                    "oemSub2CaCert": "BASE64 ENCODED OEM SUB CA2 X509 CERT",
                    "changeTimestamp": "2023-09-19T12:17:39.811648+00:00",
                    "oemProvCertValidFrom": "2023-09-19T00:00:00+00:00",
                    "oemProvCertValidUntil": "2024-09-19T00:00:00+00:00",
                    "oemProvCertSerialNumber": "16",
                    "oemRootIssuerSerialNumber": "1",
                    "oemRootAuthorityKeyIdentifier": "ee:bb:cc:dd:ee:ff:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:aa",
                    "oemRootIssuerDistinguishedName": "CN=Porsche OEM Root CA, DC=OEM, O=Porsche, C=UK"
                },
                "xsdMsgDefNamespace": "urn:iso:15118:2:2013:MsgDef",
                "contractCertValidFrom": "2023-09-19T00:00:00+00:00",
                "contractCertValidUntil": "2024-09-19T00:00:00+00:00",
                "oemProvCertSerialNumber": "16",
                "moRootAuthorityKeyIdentifier": "keyid:2A:3A:4A:5A:6A:7A:8A:9A:1B:2B:3B:4B:5B:6B:7B:8B:9B:1C:2C:3C",
                "certificateInstallationResXml": "BASE64 ENCODED EXI ENCODED ISO-15118-2 CERTIFICATE INSTALLATION REQ V2G MESSAGE",
                "moRootIssuerDistinguishedName": "O=CharIN e. V., CN=CharIN V2G Root CA G1 QA, DC=V2G",
                "contractCertEncryptedPrivateKey": "BASE64 ENCODED ENCRYPTED PRIVATE KEY FOR CONTRACT"
            }
        }
    ],
    "Links": {
        "Next": "https://api-test.shell.com/ev/plugandcharge/EU-QA/v1/events?fromOffset=61",
        "Self": "https://api-test.shell.com/ev/plugandcharge/EU-QA/v1/events"
    },
    "RequestId": "de878377-79fc-4174-8184-10e2741f27af",
    "Status": "SUCCESS"
}

NOTE: Payload structure is subject to change for now, before any commercial implementation we need to agree on the formal structure.

Check if a contract can be created for a certain PCID

Introduction

Before creating a contract an MSP can quickly check using this API if the Plug and Charge service has access to the required OEM provisioning certificate for the provided PCID.

API End Point API Functionality
GET /v1/oem/provCerts/lookupVehicle/{pcid} Check if a contract can be created for a certain PCID.

Parameters

Name Example Description
Method GET Request method
Authorization (Header) Bearer ABCD1234 Bearer token
RequestId (Header) db22ec42-f051-452a-af12-3bfcf17c0cdb GUID that identifies this request
pcid (Path) XXXX000001X000001 The PCID

Request

curl --max-time 150 --location 'https://api-test.shell.com/ev/plugandcharge/EU-QA/v1/oem/provCerts/lookupVehicle/XXXX000001X000001' \
--header 'RequestId: de878377-79fc-4174-8184-10e2741f27af' \
--header 'Authorization: Bearer ABCD1234'

Response

HTTP Code Description
200 OK OEM Prov Cert found for provided PCID
404 NOT FOUND OEM Prov Cert not found for provided PCID

Generate or update the contract

Introduction

The eMSP backend transmits the PCID, EMAID, and PnC contract bundle validity period. Utilizing this information, the PnC Service generates a signed plug and charge contract bundle. This bundle is either stored in the database for installation via EVSE or forwarded to an OEM backend.

During the contract creation, status messages will be dispatched to the subscriptionUrl. The process will persist after this endpoint has returned a 201 Created response. This behavior is intentional, aligning with the approach adopted by Hubject's implementation.

Please refer to the status messages sent to the subscriptionUrl to verify the results.

API End Point API Functionality
PUT /v1/cps/generate/signedContractData Generate or update the contract.

Parameters

Name Example Description
Method PUT Request method
Authorization (Header) Bearer ABCD1234 Bearer token
RequestId (Header) db22ec42-f051-452a-af12-3bfcf17c0cdb GUID that identifies this request
contractBegins (Body) 2023-01-01T00:00:00Z The start date of the contract
contractEnd (Body) 2023-01-01T00:00:00Z The end date of the contract
emaid (Body) UKXXXC123456785 The emaid of the contract to create or update
pcid (Body) XXXX000001X0000019 The pcid of the OEM prov cert to create the contract for
subscriptionUrl (Body) http://callbackurl.example/endpoint The endpoint to send updates about the contract creation to
xsdMsgDefNamespace (Body) urn:iso:15118:2:2013:MsgDef The schema of the V2G messages to use
metaData (Body) (not provided) Additional data related to the contract
{
  "contractBegins": "{{contractStartDate}}",
  "contractEnds": "{{contractEndDate}}",
  "emaid": "{{emaid}}",
  "pcid": "{{pcid}}",
  "subscriptionUrl": "http://callbackurl.example/endpoint",
  "xsdMsgDefNamespace": "urn:iso:15118:2:2013:MsgDef",
  "metaData": ""
}

Request

curl --max-time 150 --request PUT --location 'https://api-test.shell.com/ev/plugandcharge/EU-QA/v1/cps/generate/signedContractData' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'RequestId: 25fcda6a-aa2b-4970-903e-4071e157af1e' \
--header 'Authorization: Bearer ABCD1234' \
--data '{
  "contractBegins": "2023-09-22T00:00:00Z",
  "contractEnds": "2024-09-22T00:00:00Z",
  "emaid": "UKXXXC123456785",
  "pcid": "XXXX000001X0000019",
  "subscriptionUrl": "https://callbackurl.example/endpoint",
  "xsdMsgDefNamespace": "urn:iso:15118:2:2013:MsgDef",
  "metaData": ""
}'

Response

The response will solely consist of an HTTP status code: 201 Created. Status updates will be sent following the return of the response.

Return an ISO-15118-2 CertificateInstallationRes based on the provided CertificateInstallationReq

Introduction

The Client Party (either CPO or OEM) is required to send a CertificateInstallationReq encoded in Base64 EXI format. Upon receiving a valid and correctly formatted request, the Plug and Charge (PnC) service will respond with a CertificateInstallationRes, also encoded in Base64 EXI.

For detailed instructions on constructing a CertificateInstallationReq and validating a CertificateInstallationRes, please refer to the ISO-15118-2 specification. Additionally, we provide tools specifically designed for generating CertificateInstallationReq for testing purposes. For access to these tools or further assistance, please reach out to your designated Shell contact.

API End Point API Functionality
POST /v1/ccp/signedContractData Return an ISO-15118-2 CertificateInstallationRes based on the provided CertificateInstallationReq.

Parameters

Name Example Description
Method POST Request method
Authorization (Header) Bearer ABCD1234 Bearer token
RequestId (Header) 70280a8a-f166-4251-b17e-79507a250eb3 GUID that identifies this request
xsdMsgDefNamespace (Body) urn:iso:15118:2:2013:MsgDef The schema of the V2G messages to use
certificateInstallationReq (Body) BASE64DATA (Real example too big) Base64 encoded EXI encoded certificate installation request V2GMessage
{
      "xsdMsgDefNamespace": "urn:iso:15118:2:2013:MsgDef",
      "certificateInstallationReq": "BASE64DATA"
}

Request

curl --max-time 150 --location 'https://api-test.shell.com/ev/plugandcharge/EU-QA/v1/ccp/signedContractData' \
--header 'RequestId: 70280a8a-f166-4251-b17e-79507a250eb3' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ABCD1234' \
--data '{
      "xsdMsgDefNamespace": "urn:iso:15118:2:2013:MsgDef",
      "certificateInstallationReq": "BASE64DATA"
}'

Response

{
    "ccpResponse": {
        "emaidContent": [
            {
                "messageDef": {
                    "certificateInstallationRes": "BASE64DATA",
                    "emaid": "XXXGN000020001",
                    "metaData": null,
                    "cpsRootCertificateId": null,
                    "additionalProperties": {}
                },
                "additionalProperties": {}
            }
        ],
        "additionalProperties": {}
    },
    "additionalProperties": {}
}

Delete and revoke the contract for the provided EMAID

Introduction

The eMSP backend is responsible for sending the EMAID to terminate the PnC contract bundle prior to the end of the validity period.

Notifications regarding contract deletion and revocation will be sent to the subscriptionUrl endpoint, which was specified during the contract creation process.

API End Point API Functionality
DELETE /v1/ccp/signedContractData/{emaid} Delete and revoke the contract for the provided EMAID.

Parameters

Name Example Description
Method GET Request method
Authorization (Header) Bearer ABCD1234 Bearer token
RequestId (Header) 1fa16327-f2d5-4618-b6fc-61a736d75d43 GUID that identifies this request
emaid (Path) UKXXXC123456785 The EMAID of the contract

Request

curl --max-time 150 --request DELETE --location 'https://api-test.shell.com/ev/plugandcharge/EU-QA/v1/ccp/signedContractData/UKXXXC123456785' \
--header 'RequestId: 1fa16327-f2d5-4618-b6fc-61a736d75d43' \
--header 'Authorization: Bearer ABCD1234'

Response

HTTP Code Description
200 OK Contract Cert found and terminated for provided PCID
404 NOT FOUND Contract Cert not found for provided PCID

About us

The Shell Developer Portal is here to support partners to onboard to Shell APIs, the portal is here to take ideas to production

 

Shell logo

Login to your account