-
-
Save westdavidr/c8890e46a8f06b92df85 to your computer and use it in GitHub Desktop.
| ##API URLS | |
| - https://beta.youngliving.com/api/accounts | |
| - https://beta.youngliving.com/api/shopping | |
| - https://beta.youngliving.com/vo.dlv.api | |
| ##Authentication Endpoints | |
| - **POST**: https://beta.youngliving.com/api/accounts/token | |
| + <pre>{ | |
| email: *memberId*, | |
| memberId: *memberId*, | |
| password: *password*, | |
| userName: *memberId* | |
| }</pre> | |
| ##Commission Endpoints | |
| - **GET**: https://beta.youngliving.com/vo.dlv.api/commission/check/summary/period_id | |
| - **GET**: https://beta.youngliving.com/vo.dlv.api/commission/check/unilevel/period_id/level | |
| - **GET**: https://beta.youngliving.com/vo.dlv.api/commission/history/period_id | |
| + (0 for current period) | |
| ##Organization Endpoints | |
| - **GET**: https://beta.youngliving.com/vo.dlv.api/downline/children/user/period_id | |
| + (0 for current period) | |
| - **GET**: https://beta.youngliving.com/vo.dlv.api/downline/children/member_id/period_id | |
| + (0 for current period) | |
| - **GET**: https://beta.youngliving.com/vo.dlv.api/downline/detail/user/period_id | |
| + (0 for current period) | |
| - **GET**: https://beta.youngliving.com/vo.dlv.api/downline/detail/member_id/period_id | |
| + (0 for current period) | |
| ##Qualification Endpoints | |
| - **GET**: https://beta.youngliving.com/vo.dlv.api/downline/qualification/user/period_id | |
| + (0 for current period) | |
| ##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; | |
| } |
Has anybody produced a .Net client for the YL api yet? If not then I will develop it. Also is there an api that shows all of my orders. Finally is there an api that shows all products and their prices
@westdavidr, @rob-richards: I've successfully managed to get the token - I got a JSON object back. What from the JSON object do I use as a key to make the call to the API proper? Do I add a param to the query string of the URL, the POST body or something else? What's the format? Help appreciated.
I just tried out the API. For some reason it gives me "HTTP Error 405: Method Not Allowed". Could someone confirm that it still works.
POST to https://youngliving.com/api/accounts/token with JSON payload containing username and password.
UPDATE 09.30.2018
- Apparently URL is https://www.youngliving.com/api/accounts/token (changed)
- I'm getting HTTP/1.1 401 Unauthorized from the server
Hello guys, i got the token but now how do i get all the info?
im new in json requests, any guide or something i need to know? i dont know how to properly search in google because i dont know what i need to know exactly to make de GET request after the POST token.
Help a newbie
I too would like to know more about the shopping api. Is there a way to get products and pricing?
@westdavidr your work helped speed up my own usage of the API but it looks like it changed quite a bit.
I got the API working by doing the following:
- make sure to use
wwwin all calls instead of the bare domain name. - use a session and call
https://www.youngliving.com/vo/first to get cross site and other cookies. Use the subsequent session for the rest of the calls. - login for the token has multiple parameters:
{
"userName": username,
"email": username,
"memberId": username,
"password": password,
"rememberMe": True,
}
- When you do the login you get a json body, to create your token take the JSON string and base64 encode:
python:
token = base64.b64encode(response.content).decode()
js:
token = btoa(body)
- use the token in headers as
authtoken={token}
Does anyone have more detail on this. I can get it to return data for on the login, but token is not one of the properties. There is a signature. Is that it? Also, are there API calls to view orders and items? One of the biggest difficulties with YL's online system is that all past orders are just pdfs with no way to get a list of items purchased in some easy format.
The token is the whole body of the response after you call https://www.youngliving.com/api/accounts/token
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.
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 rowsHello, 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.
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.
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.
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.
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:
- Obtain a token by issuing a request to POST https://youngliving.com/api/accounts/token
- Received the response with user details.
- 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,
}
- Use the base64 string as the header for key authtoken
- Get https://www.youngliving.com/vo.dlv.api/downline/children/user/405 (replace user with my userID)
- Get error below. Same issue for other get request. Any idea how to get past this?
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 <customErrors> tag within a "web.config" configuration file located in the root
directory of the current web application. This <customErrors> tag should then have its "mode"
attribute set to "Off".<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
"defaultRedirect" attribute of the application's <customErrors> 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>
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
}
}
}
@westdavidr I was testing the API calls with postman, and YL updated the base URL and the required fields in the payload. I forked and updated your gist. Can you review an merge it?