Skip to content

Enroll a new customer

Overview

To enroll a new customer the following steps need to take place:

  • Product Lookup: It is recommeded that you query our products using the customer's postcode or ESI ID to make sure we have products that will be served in the customer's area. We've a handy how-to guide available here

  • Create an Account : This includes customer's address, billing information, and sales information. We use sales information to track who made this sale. It is recommended that you always make sure that each account that is created by you provides the correct salesChannel to get its attribution.

    • You can also use the uniqueReferenceNumber field to track a sale that you've made.
  • Credit check: All postpay products do require a credit check. And based on the credit check status, we either request the customer to pay a deposit, or we request our affiliates to recommend our prepay products.

    • Note: Credit check is optional if the customer agrees to pay a deposit, or legally qualifies for a waiver (will have to give us a call).
  • Add property and product: Add the address of the property and choose if the customer wants to move-in or needs a switch-request to be made. You will also have to pass the product id that customer has chosen and optionally pass a autoTopUpPaymentAmount that is needed for prepay products.

Example of an enrollment journey

The following subsections should be followed in the given order.

Create an account for a new customer

Authentication Required

Requires CAN_CREATE_ACCOUNTS permission.

Arguments

Returns

Info

We recommend that our affiliates should perform credit checks on their own. But if there is a need, we can perform credit checks on behalf of them. You can pass a social security number to the create account mutation and it will do the credit check on behalf of your organization.

Note: We won't be returning the credit score back to you. And using this service requires prior approval of the management and legal team.

1
2
3
4
5
6
7
mutation createAccount($input: CreateAccountInput!) {
    createAccount(input: $input) {
        account {
            number
        }
    }
}
# Input Variables
{
"input": {
    "accountUser": {
        givenName: "John"
        familyName: "Doe"
        email: "johnDoe@example.com"
        mobile: "2001004000"
        landline: "4407701608"
        communicationPreference: ONLINE
        languagePreference: ENGLISH
        dateOfBirth: "1996-05-24"
    }
    "billingAddress": {
        address1: "13th Madison Avenue"
        address2: "Apartment number 207"
        city: "Austin"
        state: "TX"
        zipCode: "77004"
    }
    "salesInformation": {
        salesSubchannel: COOL_ORGANIZATION
        optedInForMarketing: true
        optedInToRecommendedMessages: true
        optedInToUpdates: true
        optedInToAssociatedCompanies: false
        optedInToThirdParties: false
        optedInToSms: true
        uniqueReferenceNumber: "some-unique-reference-number"
    }
}
1
2
3
4
5
6
7
mutation createAccount($input: CreateAccountInput!) {
    createAccount(input: $input) {
        account {
            number
        }
    }
}
# Input Variables
{
"input": {
    "accountUser": {
        givenName: "John"
        familyName: "Doe"
        email: "johnDoe@example.com"
        mobile: "2001004000"
        landline: "4407701608"
        communicationPreference: ONLINE
        languagePreference: ENGLISH
        dateOfBirth: "1996-05-24"
    }
    "billingAddress": {
        address1: "13th Madison Avenue"
        address2: "Apartment number 207"
        city: "Austin"
        state: "TX"
        zipCode: "77004"
    }
    "salesInformation": {
        salesSubchannel: COOL_ORGANIZATION
        optedInForMarketing: true
        optedInToRecommendedMessages: true
        optedInToUpdates: true
        optedInToAssociatedCompanies: false
        optedInToThirdParties: false
        optedInToSms: true
        uniqueReferenceNumber: "some-unique-reference-number"
    }
    "ssn":"123456789"
}
import datetime

import pprint

import requests

# API_URL = "https://api.oeus-kraken.energy/v1/graphql/" # prod
API_URL = "https://api.oeus-kraken.systems/v1/graphql/" # test
JWT_TOKEN = "PLACE_JWT_TOKEN_HERE"
HEADERS = {
    "Authorization": f"JWT {JWT_TOKEN}"
}


def _setup_account_input(
    mobile: str = "2014007000",
    email: str = "JohnDoe@gmail.com",
    zip_code: str = "77004",
    opted_in_for_marketing: bool = True,
    opted_in_to_recommended_messages: bool = True,
    opted_in_to_updates: bool = True,
    opted_in_to_associated_companies: bool = False,
    opted_in_to_third_parties: bool = False,
    opted_in_to_sms: bool = True,
    state: str = "TX",
    sales_affiliate_subdomain: str = None,
    uniqueReferenceNumber: str = "some-unique-reference-number"
):
    sales_subchannel = "SOME ORGANIZATION"
    communication_preference = "ONLINE"
    language_preference = "ENGLISH"

    return {
        "accountUser": {
            "givenName": "John",
            "familyName": "Doe",
            "email": email,
            "mobile": mobile,
            "landline": "4407701608",
            "communicationPreference": communication_preference,
            "languagePreference": language_preference,
            "dateOfBirth": datetime.date(year=1991, month=1, day=1).isoformat(),
        },
        "billingAddress": {
            "address1": "13th Madison Avenue",
            "address2": "Apartment number 207",
            "city": "Austin",
            "state": state,
            "zipCode": zip_code,
        },
        "salesInformation": {
            "salesSubchannel": sales_subchannel,
            "salesAffiliateSubdomain": sales_affiliate_subdomain,
            "optedInForMarketing": opted_in_for_marketing,
            "optedInToRecommendedMessages": opted_in_to_recommended_messages,
            "optedInToUpdates": opted_in_to_updates,
            "optedInToAssociatedCompanies": opted_in_to_associated_companies,
            "optedInToThirdParties": opted_in_to_third_parties,
            "optedInToSms": opted_in_to_sms,
            "uniqueReferenceNumber": uniqueReferenceNumber
        },
    }

QUERY = """
    mutation createAccount($input:CreateAccountInput!){
        createAccount(input:$input){
            __typename
            account{
                number
                __typename
            }
        }
    }
"""
input = _setup_account_input()

VARIABLES={ "input": input }

session = requests.Session()
session.headers.update(HEADERS)
response = session.post(
    url=API_URL,
    json={"query": QUERY, "variables": VARIABLES}
)
pprint.pprint(response.json())
const axios = require("axios")

// const apiUrl = "https://api.oeus-kraken.energy/v1/graphql/" // Prod
const apiUrl = "https://api.oeus-kraken.systems/v1/graphql/" // Test

const jwtToken = "place_jwtToken_here"

let headers = {
  "Authorization": `JWT ${jwtToken}`
}

const setupAccountInput = (
    mobile = "2014007000",
    email = "JohnDoe@gmail.com",
    zipCode = "77004",
    optedInForMarketing = true,
    optedInToRecommendedMessages = true,
    optedInToUpdates = true,
    optedInToAssociatedCompanies = false,
    optedInToThirdParties = false,
    optedInToSms = true,
    state = "TX",
    salesAffiliateSubdomain = null
) => {
  let salesSubchannel = "SOME ORGANIZATION"
  let communicationPreference = "ONLINE"
  let languagePreference = "ENGLISH"

  return {
    "accountUser": {
      "givenName": "John",
      "familyName": "Doe",
      "email": email,
      "mobile": mobile,
      "landline": "4407701608",
      "communicationPreference": communicationPreference,
      "languagePreference": languagePreference,
      "dateOfBirth": new Date("1991-01-01").toLocaleDateString('en-CA', { year: 'numeric', month: '2-digit', day: '2-digit' })
    },
    "billingAddress": {
      "address1": "13th Madison Avenue",
      "address2": "Apartment number 207",
      "city": "Austin",
      "state": state,
      "zipCode": zipCode,
    },
    "salesInformation": {
      "salesSubchannel": salesSubchannel,
      "salesAffiliateSubdomain": salesAffiliateSubdomain,
      "optedInForMarketing": optedInForMarketing,
      "optedInToRecommendedMessages": optedInToRecommendedMessages,
      "optedInToUpdates": optedInToUpdates,
      "optedInToAssociatedCompanies": optedInToAssociatedCompanies,
      "optedInToThirdParties": optedInToThirdParties,
      "optedInToSms": optedInToSms,
    },
  }
}


const query = `
    mutation createAccount($input:CreateAccountInput!){
        createAccount(input:$input){
            __typename
            account{
                number
                __typename
            }
        }
    }
`
let input = setupAccountInput()

const variables = {"input": input}


axios({
  url: apiUrl,
  method: "post",
  data: {
    query: query,
    variables: variables,
  },
  headers: headers,
}).then((response) => {
  console.log(JSON.stringify(response.data, null, 4));
});
import axios from 'axios';

// const API_URL = "https://api.oeus-kraken.energy/v1/graphql/" // Prod
export const apiUrl = "https://api.oeus-kraken.systems/v1/graphql/" // Test

export const jwtToken = "PLACE_JWT_TOKEN_HERE"

let headers = {"Authorization": `JWT ${jwtToken}`}

export const setupAccountInput = (
    mobile = "2014007000",
    email = "JohnDoe@gmail.com",
    zipCode = "77004",
    optedInForMarketing = true,
    optedInToRecommendedMessages = true,
    optedInToUpdates = true,
    optedInToAssociatedCompanies = false,
    optedInToThirdParties = false,
    optedInToSms = true,
    state = "TX",
    salesAffiliateSubdomain = null
) => {
  let salesSubchannel = "SOME ORGANIZATION"
  let communicationPreference = "ONLINE"
  let languagePreference = "ENGLISH"

  return {
    "accountUser": {
      "givenName": "John",
      "familyName": "Doe",
      "email": email,
      "mobile": mobile,
      "landline": "4407701608",
      "communicationPreference": communicationPreference,
      "languagePreference": languagePreference,
      "dateOfBirth": new Date("1991-01-01").toLocaleDateString('en-CA', { year: 'numeric', month: '2-digit', day: '2-digit' })
    },
    "billingAddress": {
      "address1": "13th Madison Avenue",
      "address2": "Apartment number 207",
      "city": "Austin",
      "state": state,
      "zipCode": zipCode,
    },
    "salesInformation": {
      "salesSubchannel": salesSubchannel,
      "salesAffiliateSubdomain": salesAffiliateSubdomain,
      "optedInForMarketing": optedInForMarketing,
      "optedInToRecommendedMessages": optedInToRecommendedMessages,
      "optedInToUpdates": optedInToUpdates,
      "optedInToAssociatedCompanies": optedInToAssociatedCompanies,
      "optedInToThirdParties": optedInToThirdParties,
      "optedInToSms": optedInToSms,
    },
  }
}

export const mutation = `
  mutation createAccount($input:CreateAccountInput!){
      createAccount(input:$input){
          __typename
          account{
              number
              __typename
          }
      }
  }
`

let input = setupAccountInput()

export const variables = {"input": input}

axios({
  url: apiUrl,
  method: "post",
  data: {
    query: mutation,
    variables: variables,
  },
  headers: headers,
}).then((response) => {
  console.log(JSON.stringify(response.data, null, 4));
});
Expected error messages
  • Check for a valid email address.
    • If it receives an invalid email address, it will raise Invalid email address: {email}." error.
  • Check for a valid USA zip code.
    • If it receives an invalid zipcode, it will raise '{zip_code}' is not a valid USA postcode." error.
  • Check for a valid USA phone number.
    • If it finds an invalid mobile/landline/phone number, it will raise '{mobile/landline/phone number}' is not a valid phone number" error.
  • For any other errors, it will return a generic errror message such as Cannot create an account.

Add credit score for an account

If you are using your own credit service, we require that you send us the credit score using the storeCreditScore mutation 🔗

Check credit score status

It is important that you check the credit score status to verify if the customer needs to pay a deposit or not. The status can be one of the following:

  • PASSED
  • FAILED
  • NOT_AVAILABLE

If you've received a FAILED status, we either require a deposit from the customer or we request our affiliates to recommend our prepay products. If the customer has still choosen to pay a deposit, we require them to contact us. Soon this will be handled via an API call.

Authentication Required

Requires CAN_CREATE_ACCOUNTS permission.

Arguments

  • accountNumber: String!

Returns

1
2
3
4
5
query creditCheckStatus($accountNumber: String!) {
  creditCheckStatus(accountNumber: $accountNumber) {
    status
  }
}
Expected error messages
  • If the given account number is invalid/not found.
    • It returns - Unauthorized.
  • You are not authorized to view this account's credit score status.

Add property and product

In this example we've asserted the following scenario:

  • The customer wants to perform a move in request which is suggested by the PENDING_MOVE_IN_REQUEST enum as an input for the enrollmentType.
  • The customer has selected a product with the id: 18 and they've agreed to it's rates. You can get the product id by using the following how to guides:

    • Get products with rates (supports kwh usage argument) 🔗

    • Get products with rates pre-calculated for 500 kWh, 1000 kWh, and 2000 kWh usages 🔗

Authentication Required

Requires CAN_ADD_PROPERTIES_TO_SHELL_ACCOUNTS permissions.

Arguments

Returns

Info

If you do not provide an effectiveFrom input to addPropertyToShellAccount, the switch/move-in request will default to the current CST time. In other words, if a customer wants to switch on the next day, but if we don't receive that input, instead of switching them tomorrow, we might send a switch request for today.

Note: effectiveFrom should always be in UTC and follow the iso8601 standard.

For postpay product

1
2
3
4
5
6
7
8
9
mutation addPropertyToShellAccount(
    $input: AddPropertyToShellAccountInputType!
    ) {
    addPropertyToShellAccount(input: $input) {
        addPropertyToShellAccountData {
            esiId
        }
    }
}
# Input variables
{
    "input": {
        "accountNumber": "A-B8AAF52D"
        "esiId": "1008901000141570010101"
        "addressLine1": "26197 Avenue"
        "addressLine2": "Shady Woods"
        "addressLine3": "Lane"
        "city": "Houston"
        "state": "TX"
        "postcode": "77057"
        "enrollmentType": PENDING_MOVE_IN_REQUEST
        "productId": "18"
        # Without an effectiveFrom input, the request will
        # default to the current CST time.
        "effectiveFrom": "2022-03-17T21:00:00-05:00"
    }
}
import datetime

import pprint

import requests

# API_URL = "https://api.oeus-kraken.energy/v1/graphql/" # prod
API_URL = "https://api.oeus-kraken.systems/v1/graphql/" # test
JWT_TOKEN = "PLACE_JWT_TOKEN_HERE"
HEADERS = {
    "Authorization": f"JWT {JWT_TOKEN}"
}

input = {
"accountNumber": "A-B8AAF52D",
"esiId": "1008901000141570010100",
"addressLine1": "26197 Avenue",
"addressLine2": "Shady Woods",
"addressLine3": "St",
"city": "Houston",
"state": "TX",
"postcode": "77057",
"enrollmentType": "PENDING_MOVE_IN_REQUEST",
"productId": "18",
# Without an effectiveFrom input, the request will
# default to the current CST time.
"effectiveFrom": "2022-03-17T21:00:00-05:00",
}


QUERY = """
mutation addPropertyToShellAccount(
    $input: AddPropertyToShellAccountInputType!
    ) {
    addPropertyToShellAccount(input: $input) {
        addPropertyToShellAccountData {
            esiId
        }
    }
}
"""

VARIABLES = {"input": input}


session = requests.Session()
session.headers.update(HEADERS)
response = session.post(
    url=API_URL,
    json={"query": QUERY, "variables": VARIABLES}
)
pprint.pprint(response.json())
const axios = require("axios")

// const apiUrl = "https://api.oeus-kraken.energy/v1/graphql/" // Prod
const apiUrl = "https://api.oeus-kraken.systems/v1/graphql/" // Test

const jwtToken = "PLACE_JWT_TOKEN_HERE"

let headers = {
  "Authorization": `JWT ${jwtToken}`
}

const input = {
    "accountNumber": "A-B8AAF52D",
    "esiId": "1008901000141570010101",
    "addressLine1": "26197 Avenue",
    "addressLine2": "Shady Woods",
    "addressLine3": "Lane",
    "city": "Houston",
    "state": "TX",
    "postcode": "77057",
    "enrollmentType": "PENDING_MOVE_IN_REQUEST",
    "productId": "18",
     // Without an effectiveFrom input, the request will
     // default to the current CST time.
    "effectiveFrom": new Date("2022-03-17T21:00:00-05:00")
};


const mutation = `
mutation addPropertyToShellAccount(
    $input: AddPropertyToShellAccountInputType!
    ) {
    addPropertyToShellAccount(input: $input) {
        addPropertyToShellAccountData {
            esiId
        }
    }
}
`

const variables = {"input": input}

axios({
  url: apiUrl,
  method: "post",
  data: {
    query: mutation,
    variables: variables,
  },
  headers: headers,
}).then((response) => {
  console.log(JSON.stringify(response.data, null, 4));
});
import axios from 'axios';

// const API_URL = "https://api.oeus-kraken.energy/v1/graphql/" // Prod
export const apiUrl = "https://api.oeus-kraken.systems/v1/graphql/" // Test

export const jwtToken = "PLACE_JWT_TOKEN_HERE"

let headers = {"Authorization": `JWT ${jwtToken}`}

let input = {
  "accountNumber": "A-B8AAF52D",
  "esiId": "1008901000141570010101",
  "addressLine1": "26197 Avenue",
  "addressLine2": "Shady Woods",
  "addressLine3": "Lane",
  "city": "Houston",
  "state": "TX",
  "postcode": "77057",
  "enrollmentType": "PENDING_MOVE_IN_REQUEST",
  "productId": "18",
   // Without an effectiveFrom input, the request will
   // default to the current CST time.
  "effectiveFrom": new Date("2022-03-17T21:00:00-05:00")
};


export const mutation = `
mutation addPropertyToShellAccount(
    $input: AddPropertyToShellAccountInputType!
    ) {
    addPropertyToShellAccount(input: $input) {
        addPropertyToShellAccountData {
            esiId
        }
    }
}
`

export const variables = {"input": input}

axios({
  url: apiUrl,
  method: "post",
  data: {
    query: mutation,
    variables: variables,
  },
  headers: headers,
}).then((response) => {
  console.log(JSON.stringify(response.data, null, 4));
});

For prepay product

Customers could choose what amount they're willing to allow us takeout to top up their account once their balance reaches a threshold. This amount should be passed via the autoTopUpPaymentAmount in this mutation.

1
2
3
4
5
6
7
8
9
mutation addPropertyToShellAccount(
    $input: AddPropertyToShellAccountInputType!
    ) {
    addPropertyToShellAccount(input: $input) {
        addPropertyToShellAccountData {
            esiId
        }
    }
}
# Input variables
{
    "input": {
        "accountNumber": "A-B8AAF52D"
        "esiId": "1008901000141570010101"
        "addressLine1": "26197 Avenue"
        "addressLine2": "Shady Woods"
        "addressLine3": "Lane"
        "city": "Houston"
        "state": "TX"
        "postcode": "77057"
        "enrollmentType": PENDING_MOVE_IN_REQUEST
        "productId": "18"
        # autoTopUpPaymentAmount is in cents
        "autoTopUpPaymentAmount": 1500

        # Without an effectiveFrom input, the request will
        # default to the current CST time.
        "effectiveFrom": "2022-03-17T21:00:00-05:00"
    }
}
import datetime

import pprint

import requests

# API_URL = "https://api.oeus-kraken.energy/v1/graphql/" # prod
API_URL = "https://api.oeus-kraken.systems/v1/graphql/" # test
JWT_TOKEN = "PLACE_JWT_TOKEN_HERE"
HEADERS = {
    "Authorization": f"JWT {JWT_TOKEN}"
}

input = {
    "accountNumber": "A-B8AAF52D",
    "esiId": "1008901000141570010101",
    "addressLine1": "26197 Avenue",
    "addressLine2": "Shady Woods",
    "addressLine3": "Lane",
    "city": "Houston",
    "state": "TX",
    "postcode": "77057",
    "enrollmentType": "PENDING_MOVE_IN_REQUEST",
    "productId": "18",
    # autoTopUpPaymentAmount is in cents
    "autoTopUpPaymentAmount": 1500,

    # Without an effectiveFrom input, the request will
    # default to the current CST time.
    "effectiveFrom": "2022-03-17T21:00:00-05:00",
}


QUERY = """
mutation addPropertyToShellAccount(
    $input: AddPropertyToShellAccountInputType!
    ) {
    addPropertyToShellAccount(input: $input) {
        addPropertyToShellAccountData {
            esiId
        }
    }
}
"""

VARIABLES = {"input": input}


session = requests.Session()
session.headers.update(HEADERS)
response = session.post(
    url=API_URL,
    json={"query": QUERY, "variables": VARIABLES}
)
pprint.pprint(response.json())
const axios = require("axios")

// const apiUrl = "https://api.oeus-kraken.energy/v1/graphql/" // Prod
const apiUrl = "https://api.oeus-kraken.systems/v1/graphql/" // Test

const jwtToken = "PLACE_JWT_TOKEN_HERE"

let headers = {
  "Authorization": `JWT ${jwtToken}`
}

const input = {
    "accountNumber": "A-B8AAF52D",
    "esiId": "1008901000141570010101",
    "addressLine1": "26197 Avenue",
    "addressLine2": "Shady Woods",
    "addressLine3": "Lane",
    "city": "Houston",
    "state": "TX",
    "postcode": "77057",
    "enrollmentType": "PENDING_MOVE_IN_REQUEST",
    "productId": "18",
     // autoTopUpPaymentAmount is in cents
    "autoTopUpPaymentAmount": "1500",

     // Without an effectiveFrom input, the request will
     // default to the current CST time.
    "effectiveFrom": new Date("2022-03-17T21:00:00-05:00")
};


const mutation = `
mutation addPropertyToShellAccount(
    $input: AddPropertyToShellAccountInputType!
    ) {
    addPropertyToShellAccount(input: $input) {
        addPropertyToShellAccountData {
            esiId
        }
    }
}
`

const variables = {"input": input}

axios({
  url: apiUrl,
  method: "post",
  data: {
    query: mutation,
    variables: variables,
  },
  headers: headers,
}).then((response) => {
  console.log(JSON.stringify(response.data, null, 4));
});
import axios from 'axios';

// const API_URL = "https://api.oeus-kraken.energy/v1/graphql/" // Prod
export const apiUrl = "https://api.oeus-kraken.systems/v1/graphql/" // Test

export const jwtToken = "PLACE_JWT_TOKEN_HERE"

let headers = {"Authorization": `JWT ${jwtToken}`}

let input = {
  "accountNumber": "A-B8AAF52D",
  "esiId": "1008901000141570010101",
  "addressLine1": "26197 Avenue",
  "addressLine2": "Shady Woods",
  "addressLine3": "Lane",
  "city": "Houston",
  "state": "TX",
  "postcode": "77057",
  "enrollmentType": "PENDING_MOVE_IN_REQUEST",
  "productId": "18",
   // autoTopUpPaymentAmount is in cents
  "autoTopUpPaymentAmount": "1500",

   // Without an effectiveFrom input, the request will
   // default to the current CST time.
  "effectiveFrom": new Date("2022-03-17T21:00:00-05:00")
};


export const mutation = `
mutation addPropertyToShellAccount(
    $input: AddPropertyToShellAccountInputType!
    ) {
    addPropertyToShellAccount(input: $input) {
        addPropertyToShellAccountData {
            esiId
        }
    }
}
`

export const variables = {"input": input}

axios({
  url: apiUrl,
  method: "post",
  data: {
    query: mutation,
    variables: variables,
  },
  headers: headers,
}).then((response) => {
  console.log(JSON.stringify(response.data, null, 4));
});
Expected error messages
  • UNAUTHORIZED
    • If the given account number is invalid/not found.
  • Product not found
    • If the given product id is invalid/not found.
  • Given ESI ID: {esi_id} is not served by us.
    • If the given ESI ID is served by a service provider in which Octopus Energy USA does not operate.
  • Cannot reassign property for account: {account.number} with the given effective at value : {effective_at}.
    • Customer will need to manually contact the operations team to handle this case.
  • Existing meter point with the status: {meter_point.status} cannot be reassigned. Meter point should have one of the ['LOST', 'INITIAL', 'CANCELLED_APPLICATION'] statuses to be reassigned.
    • Customer will need to manually contact the operations team to handle this case.
Back to top