Skip to content

Instantly share code, notes, and snippets.

@westdavidr
Last active May 7, 2022 15:41
Show Gist options
  • Save westdavidr/c8890e46a8f06b92df85 to your computer and use it in GitHub Desktop.
Save westdavidr/c8890e46a8f06b92df85 to your computer and use it in GitHub Desktop.
Young Living API reference

##API URLS


##Authentication

To obtain a token, issue a request to POST https://youngliving.com/api/accounts/token

  • The request must be a HTTP POST request.
  • The request must include a Content-Type header with the value of application/json.
  • The body of the request must in JSON format with memberId and password.

Request body

{
    "memberId": "",
    "password": ""
}

Example request

POST /api/accounts/token HTTP/1.1
Host: youngliving.com
Content-Type: application/json

{
    "memberId": "123456",
    "password": "sosecret"
}

##Organization Base URL: https://youngliving.com/vo.dlv.api/downline ###Endpoints

  • GET /children/user/{periodid}
  • GET /children/member_id/{periodid}
  • GET /detail/user/{periodid}
  • GET /detail/{memberid}/{periodid}

###Examples

  • (0 can be used in place of {periodid} for current period)

####Get downline for authorized user. Example Request:

GET
https://youngliving.com/vo.dlv.api/downline/children/user/405

Example Response:

{
	"customerid": "1449977",
	"currentperiodid": 406,
	"periodid": 405,
	"chartstartperiod": 398,
	"chartendperiod": 405,
	"totalchildren": 74,
	"legs": [ ]
}

####Get downline for specific user Example Request:

GET
https://youngliving.com/vo.dlv.api/downline/children/1223344/405

Example Response:

{
	"customerid": 1223344,
	"currentperiodid": 406,
	"periodid": 405,
	"chartstartperiod": 398,
	"chartendperiod": 405,
	"totalchildren": 15,
	"legs": [ ]
}

####Get details for authorized user. Example Request:

GET 
https://youngliving.com/vo.dlv.api/downline/detail/user/405

Example Response:

{
	"customerid": 123456,
	"name": "BLOW, JOE",
	"customertype": 2,
	"email": "test@example.com",
	"mainphone": "1234567891",
	"datesignedup": "5/1/2013 12:27:52 PM",
	"dateactivated": "5/1/2013 12:27:52 PM",
	"onhold": false,
	"activitystatusid": 1,
	"holdreason": "",
	"avatarimage": "",
	"volume": { },
	"rank": { },
	"address": { },
	"autoship": { },
	"sponsor": { },
	"enroller": { }
}

####Get details for a specific user. Example Request:

GET 
https://youngliving.com/vo.dlv.api/downline/detail/user/405

Example Response:

{
	"customerid": 1223344,
	"name": "MEMBER, COOL",
	"customertype": 2,
	"email": "test@example.net",
	"mainphone": "1234567891",
	"datesignedup": "11/16/2013 12:19:32 PM",
	"dateactivated": "11/16/2013 12:19:32 PM",
	"onhold": false,
	"activitystatusid": 1,
	"holdreason": "",
	"avatarimage": "",
	"volume": { },
	"rank": { },
	"address": { },
	"autoship": { },
	"sponsor": { },
	"enroller": { },
	"sponsorpath": [ ]
}

##Commission Base URL: https://youngliving.com/vo.dlv.api/commission ###Endpoints

  • GET: /check/summary/{periodid}
  • GET: /check/unilevel/{periodid}/{levelnum}
  • GET: /history/{periodid}

###Examples

  • (0 can be used in place of {periodid} for current period)

####Get commission check summary for a specific commission period. Example Request:

GET
https://youngliving.com/vo.dlv.api/commission/check/summary/405

Example Result:

{
  "customerid":"123456",
  "checkid":"12345678",
  "checkdate":"11/17/2014",
  "periodid":"405",
  "checktotal":"314.39",
  "totalcommission":"317.39",
  "currencyunit":"USD",
  "dgyf":"0",
  "paidasrankid":2,
  "maxrankid":2,
  "volume":{
    "ogv":4635.5,
    "pv":290.25,
    "pgv":4635.5
  },
  "retail":{
    "commission":"11.84"
  },
  "unilevel":{
    "commission":"229.71",
    "levels":[
      {
        "levelnum":1,
        "commission":"$142.83"
      },
      {
        "levelnum":2,
        "commission":"$63.49"
      },
      {
        "levelnum":3,
        "commission":"$23.39"
      }
    ]
  },
  "faststart":{
    "commission":"75.84",
    "levels":[
      {
        "levelnum":1,
        "commission":"$8.44"
      },
      {
        "levelnum":2,
        "commission":"$67.40"
      }
    ]
  },
  "personalgen":{
    "commission":"0"
  },
  "generations":{
    "commission":"0"
  },
  "risingstar":{
    "commission":"0"
  },
  "leadership":{
    "commission":"0"
  },
  "diamondexpress":{
    "commission":"0"
  },
  "starterkit":{
    "commission":"0"
  },
  "adjustments":{
    "total":"-3",
    "items":[
      {
        "description":"Maintenance Fee",
        "amount":"-3",
        "commledgertypeid":2
      }
    ]
  }
}

#####Get commission check details for a specific level in a commission period. Example Request:

GET
https://youngliving.com/vo.dlv.api/commission/check/unilevel/405/1

Example Result:

{
  "customerid":123456,
  "periodid":406,
  "commissionvolume":1785,
  "percentage":8,
  "commissionearned":"$142.83",
  "unilevel":{
    "levels":[
      {
        "membernum":123445,
        "membername":"MEMBER, COOL",
        "commissionvolume":75.25,
        "percentage":8.0,
        "commissionsearned":6.02
      },
      ...
    ]
  }
}

#####Get commission check details for a specific level in a commission period. Example Request:

GET
https://youngliving.com/vo.dlv.api/commission/history/405

Example Result:

{
  "customerid":1449977,
  "checks":[
    {
      "periodid":405,
      "checknumber":"12345678",
      "checkdate":"11/17/2014",
      "amount":317.39,
      "amountformatted":"$317.39",
      "currency":"USD"
    },
    ...
  ]
}

##Qualification Endpoints


##Essential Rewards Base URL: https://youngliving.com/api/shopping/essential-rewards ###Endpoints

  • GET: /info

###Examples

####Get essential rewards information Example Request:

GET
https://youngliving.com/api/shopping/essential-rewards/info

Example Result:

{
	"totalPoints": 96,
	"totalExpiringPoints30Days": 0,
	"consecutiveMonthsOfErOrders": 12,
	"earningPercentage": 15,
	"availableMonthlyPoints": 96,
	"monthsBeforePercentageIncrease": 0,
	"nextEarningRate": 0,
	"isEnrolled": true,
	"payments": [ ],
	"legacyOtgProcessingDayOfMonth": 1,
	"legacyNfrProcessingDayOfMonth": 1,
	"isErTemplateConfirmed": true,
	"areErDeliveriesValid": true,
	"doesTemplateMeetMinPv": true,
	"otg": {
		"processingDate": {
			"year": 2014,
			"month": 12,
			"day": 1
		}
	},
	"nfr": {
		"processingDate": {
			"year": 2014,
			"month": 11,
			"day": 1
		}
	}
}

##Helpers

function getPeriodId(date) { // Defaults to Current Period if you leave 'date' empty
    date = date instanceof Date ? date : new Date();
    return (date.getFullYear() * 12 + date.getMonth() + 1) - (2014 * 12 + 5) + 400;
}
@pizzapanther
Copy link

The token is the whole body of the response after you call https://www.youngliving.com/api/accounts/token

@brassnkeys
Copy link

The token is the whole body of the response after you call https://www.youngliving.com/api/accounts/token

Thanks. I was able to determine what was wrong. It works with the base64.b64encode(res.content) after I realized that my module variable wasn't global so the token was empty when I went to use it again. Python mistake.

Any thoughts on other URLs though? I really would like to pull orders from the past. My goal is to pull all the items ordered in each order#, etc. All the URLs listed here seem to focus on just the organization structure, commissions, etc.

@pizzapanther
Copy link

I'm not certain about URLs since i'm not doing that but I was able to get the info I needed by running a report and exporting the data to a CSV. Then parsing the CSV. Maybe there is a similar report for items ordered?

This is dumping a user's contacts:

def get_contacts(self):
    # need the period ID from the summary to download a report
    summary_url = 'https://www.youngliving.com/vo.dlv.api//dashboard/summary'
    response = self.session.get(summary_url, headers=self.headers())
    self.raise_exception(response)
    summary = response.json()

    load_url = 'https://www.youngliving.com/vo.dlv.api//reportdata/v2/load'
    load_data = {
      "reportid": "all",
      "periodid": summary['organization'][0]['periodid'],
      "sortby":"",
      "sortdesc":1,
      "pagenumber":1,
      "filters":[],
      "columns":[{"id":"memberid"},{"id":"name"},{"id":"email"},{"id":"address"},{"id":"phone"}],
      "download":"true",
      "format":"CSV"
    }

    response = self.session.post(load_url, headers=self.headers(), json=load_data)
    self.raise_exception(response)

    csv_url = 'https://www.youngliving.com/vo.dlv.api/reports/download/All%20Accounts/{reportid}/{guid}/1/en-US'.format(
      **response.json()
    )
    response = self.session.get(csv_url, headers=self.headers())
    self.raise_exception(response)
    fh = io.StringIO(response.text)
    reader = csv.DictReader(fh)
    rows = []
    for row in reader:
      rows.append(row)
    fh.close()

    return rows

@artiisgithub
Copy link

Hello, does anyone have any CORS issue with Vuejs? Was trying to obtain the token but seeing
'Access to XMLHttpRequest at 'https://youngliving.com/api/accounts/token' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.'

Any advice? Thanks a lot.

@pizzapanther
Copy link

The token request has the header access-control-allow-origin: https://www.youngliving.com so that would cause problems.

Other APIs have the header access-control-allow-origin: * so they should work.

I've been making all my calls on my backend to avoid CORS issues and then just sending the frontend necessary data.

@gera3d
Copy link

gera3d commented May 26, 2020

Hello,
Has anyone tried loading this data into a google spreadsheet? What would doing that look like? As I add users to my downline I want to add them to my spreadsheet.

@pizzapanther
Copy link

You should be able to download that data in their back office as a CSV then loading into a spreadsheet. You could do this automatically with their API but you could also do it manually.

@7even84
Copy link

7even84 commented Jun 2, 2020

Hey hie guys! Thanks so much for this work! I been trying to get past the token phase but seems to be hitting an issue. Thanks in advance for the help :)

My steps:

  1. Obtain a token by issuing a request to POST https://youngliving.com/api/accounts/token
  2. Received the response with user details.
  3. Use the below info format (Using the details received and then encode into Base64) -- Do we need to encode the whole received message of the below fields are sufficient?

{
"userName": username,
"email": username,
"memberId": username,
"password": password,
"rememberMe": True,
}

  1. Use the base64 string as the header for key authtoken
  2. Get https://www.youngliving.com/vo.dlv.api/downline/children/user/405 (replace user with my userID)
  3. Get error below. Same issue for other get request. Any idea how to get past this?
<title>Runtime Error</title> <style> body { font-family: "Verdana"; font-weight: normal; font-size: .7em; color: black; }
	p {
		font-family: "Verdana";
		font-weight: normal;
		color: black;
		margin-top: -5px
	}

	b {
		font-family: "Verdana";
		font-weight: bold;
		color: black;
		margin-top: -5px
	}

	H1 {
		font-family: "Verdana";
		font-weight: normal;
		font-size: 18pt;
		color: red
	}

	H2 {
		font-family: "Verdana";
		font-weight: normal;
		font-size: 14pt;
		color: maroon
	}

	pre {
		font-family: "Consolas", "Lucida Console", Monospace;
		font-size: 11pt;
		margin: 0;
		padding: 0.5em;
		line-height: 14pt
	}

	.marker {
		font-weight: bold;
		color: black;
		text-decoration: none;
	}

	.version {
		color: gray;
	}

	.error {
		margin-bottom: 10px;
	}

	.expandable {
		text-decoration: underline;
		font-weight: bold;
		color: navy;
		cursor: hand;
	}

	@media screen and (max-width: 639px) {
		pre {
			width: 440px;
			overflow: auto;
			white-space: pre-wrap;
			word-wrap: break-word;
		}
	}

	@media screen and (max-width: 479px) {
		pre {
			width: 280px;
		}
	}
</style>
<span><H1>Server Error in '/vo.dlv.api' Application.<hr width=100% size=1 color=silver></H1>

        <h2> <i>Runtime Error</i> </h2></span>

<font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif ">

	<b> Description: </b>An application error occurred on the server. The current custom error settings for this
	application prevent the details of the application error from being viewed remotely (for security reasons). It
	could, however, be viewed by browsers running on the local server machine.
	<br><br>

	<b>Details:</b> To enable the details of this specific error message to be viewable on remote machines, please
	create a &lt;customErrors&gt; tag within a &quot;web.config&quot; configuration file located in the root
	directory of the current web application. This &lt;customErrors&gt; tag should then have its &quot;mode&quot;
	attribute set to &quot;Off&quot;.<br><br>

	<table width=100% bgcolor="#ffffcc">
		<tr>
			<td>
				<code><pre>

<!-- Web.Config Configuration File -->

<configuration>
<system.web>
<customErrors mode="Off"/>
</system.web>
</configuration>

			</td>
		</tr>
	</table>

	<br>

	<b>Notes:</b> The current error page you are seeing can be replaced by a custom error page by modifying the
	&quot;defaultRedirect&quot; attribute of the application&#39;s &lt;customErrors&gt; configuration tag to point
	to a custom error page URL.<br><br>

	<table width=100% bgcolor="#ffffcc">
		<tr>
			<td>
				<code><pre>

<!-- Web.Config Configuration File -->

<configuration>
<system.web>
<customErrors mode="RemoteOnly" defaultRedirect="mycustompage.htm"/>
</system.web>
</configuration>

			</td>
		</tr>
	</table>

	<br>

</body>

@jrcano
Copy link

jrcano commented Aug 3, 2020

Here is a sample in .net c#

using (var client = new HttpClient())
{
string baseURL = @"https://www.youngliving.com/";
client.BaseAddress = new Uri(baseURL);
var credentials = new
{
memberId = @"your MemberId",
password = "your Password"
};
var jsonCredentials = JsonConvert.SerializeObject(credentials);
var requestBody = new StringContent(jsonCredentials);
requestBody.Headers.ContentType = new MediaTypeHeaderValue("application/json");
//HTTP POST
var getTask = client.PostAsync("api/accounts/token", requestBody);
getTask.Wait();
//res = getTask.Result.StatusCode.ToString();
if (getTask.Result.IsSuccessStatusCode)
{
var readTask = getTask.Result.Content.ReadAsStringAsync();
readTask.Wait();
var plainToken = System.Text.Encoding.UTF8.GetBytes(readTask.Result);
var token64 = System.Convert.ToBase64String(plainToken);
client.DefaultRequestHeaders.Add("authtoken", token64);
// The last parameter is the period Id, if you don't know it you can use 0 for the current Period
var getUser = client.GetAsync("vo.dlv.api/downline/children/yourMemberId/0");
getUser.Wait();
if (getUser.Result.IsSuccessStatusCode)
{
var readUser = getUser.Result.Content.ReadAsStringAsync();
readUser.Wait();
// The result is a json with your results
}
}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment