Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invoices #539

Open
wannesdemaeght opened this issue Mar 4, 2022 · 32 comments
Open

Invoices #539

wannesdemaeght opened this issue Mar 4, 2022 · 32 comments

Comments

@wannesdemaeght
Copy link

wannesdemaeght commented Mar 4, 2022

in the endpoints file there is some documentation about invoices.
I would like to automatically download my supercharging invoices, but can not get it to work.

"DOWNLOAD_CHARGING_INVOICE": {
    "TYPE": "GET",
    "URI": "bff/v2/mobile-app/charging/invoice/{uuid}",
    "AUTH": true
  },
  "DOWNLOAD_CHARGING_SUBSCRIPTION_INVOICE": {
    "TYPE": "GET",
    "URI": "bff/v2/mobile-app/charging/subscription/invoice/{invoiceId}",
    "AUTH": true
  },

using these endpoints needs a uuid or invoiceId, which I am trying to obtain with this endpoint:

  "MANAGE_GET_SUBSCRIPTION_INVOICES": {
    "TYPE": "GET",
    "URI": "bff/v2/mobile-app/subscriptions/invoices",
    "AUTH": true
  },

I am using this url:
https://owner-api.teslamotors.com/bff/v2/mobile-app/subscriptions/invoices

I am using GET, with requestheader application/json
params is: {"vehicle_id":"xxxxxxxxxxxx"} (id is correct, and works for all other api requests)

response is:
{"response":null,"error":"param is missing or the value is empty: vehicle_id","error_description":""}

I tried attaching the vehicle_id in the url, as needs to be done for other calls, but then I get a 404 error.
Any help?

@jamesdeck
Copy link

Curious about this too. I've tried for days to get supercharging costs from the API but have not gotten anywhere.

@idriskhenchil
Copy link

What headers are you sending?

@timdorr
Copy link
Owner

timdorr commented May 21, 2022

The BFF (backend-for-frontend) endpoints don't appear to authenticate the same way as the other vehicle endpoints do. I'd love to figure out what's going on here. Since they started obfuscating the JavaScript bundle in the app, it's gotten a little more difficult to figure out what the app is up to with these endpoints. I either need to packet sniff or just de-obfuscate the JS bundle, but we should probably focus a bit on figuring out how to call these endpoints.

@idriskhenchil
Copy link

The BFF (backend-for-frontend) endpoints don't appear to authenticate the same way as the other vehicle endpoints do. I'd love to figure out what's going on here. Since they started obfuscating the JavaScript bundle in the app, it's gotten a little more difficult to figure out what the app is up to with these endpoints. I either need to packet sniff or just de-obfuscate the JS bundle, but we should probably focus a bit on figuring out how to call these endpoints.

I've been able to packet sniff the app and I'll post that information here when I get a chance. Currently trying to packet sniff the actual car as well, but that's proving to be a little tricky so far.

@idriskhenchil
Copy link

idriskhenchil commented May 22, 2022

Through checking the HTTP requests on the app, I've been able to get Invoice data through:

POST https://ownership.tesla.com/graphql?deviceLanguage=en&deviceCountry=US&vin={vin}&operationName=getChargingHistoryV2

The request is as follows:

POST /graphql?deviceLanguage=en&deviceCountry=US&vin={VIN}&operationName=getChargingHistoryV2 HTTP/1.1
Host: ownership.tesla.com
Accept: */*
Authorization: Bearer {token}
Accept-Encoding: gzip, deflate, br
Accept-Language: en
Cache-Control: no-cache
charset: utf-8
Content-Length: 1376
User-Agent: Tesla/1032 CFNetwork/1331.0.7 Darwin/21.4.0
Connection: keep-alive
x-tesla-user-agent: TeslaApp/4.8.1/5e1bfb8d0d/ios/15.4.1
Content-Type: application/json
x-txid: {x-txid}
Cookie: bm_sv={value}; ak_bmsc={value}

Which in turn will return roughly the following response

"charging": {
        "historyV2": {
          "data": [{
            "countryCode": "US",
            "programType": "PTSCH",
            "billingType": "IMMEDIATE",
            "vin": "{VIN}",
            "credit": null,
            "invoices": null,
            "chargeSessionId": "1234565-0-12345566",
            "siteLocationName": "LOCATION",
            "chargeStartDateTime": "2022-05-21T21:06:18-04:00",
            "chargeStopDateTime": "2022-05-21T21:46:20-04:00",
            "unlatchDateTime": "2022-05-21T21:46:21-04:00",
            "fees": [{
              "sessionFeeId": 1234566,
              "feeType": "CHARGING",
              "payorUid": null,
              "amountDue": null,
              "currencyCode": "USD",
              "pricingType": "PAYMENT",
              "usageBase": 61,
              "usageTier1": 10,
              "usageTier2": 12,
              "usageTier3": 17,
              "usageTier4": 0,
              "rateBase": 0.17,
              "rateTier1": 0,
              "rateTier2": 0,
              "rateTier3": null,
              "rateTier4": null,
              "totalTier1": 0,
              "totalTier2": 0,
              "totalTier3": 0,
              "totalTier4": 0,
              "uom": "kwh",
              "isPaid": true,
              "uid": 1234567,
              "totalBase": 10.37,
              "totalDue": 10.37,
              "netDue": 10.37,
              "status": "PAID"
            }],
            "vehicleMakeType": "TESLA",
            "sessionId": 1234567,
            "surveyCompleted": null,
            "surveyType": null,
            "postId": "0",
            "cabinetId": "vehicleMakeType",
            "din": ""
          }

I've only been able to view the request on the Tesla app. I'm still trying to figure out the header situation since I believe the x-txid or the cookies are single use.

If you are trying to get the actual PDF invoice instead, you can try:

GET https://ownership.tesla.com/mobile-app/charging/invoice/{INVOICE_ID}?deviceCountry=US&deviceLanguage=en&vin={VIN}

Which takes the same headers as above.

I do get a 401 when trying to make the request through a REST client, which I think may be related to this

@wannesdemaeght
Copy link
Author

Any update on this? As there is no way to get my invoices (premium connectivity and supercharging) via mail, I’d like to access them via api…

@davidhodge
Copy link

I'm also curious if you found anything here. If i were to guess, the secret is in the cookies.

@idriskhenchil
Copy link

PDF invoices can be accessed with

GET https://ownership.tesla.com/mobile-app/charging/invoice/{INVOICE_ID}?deviceCountry=US&deviceLanguage=en&vin={VIN}

The inconvenience is that you'd need to know the INVOICE_ID.

@davidhodge
Copy link

thanks @idriskhenchil, we're still a bit stuck on getting the list of invoices. Presently getting back "Bad Request". Perhaps missing some headers.

@idriskhenchil
Copy link

@davidhodge Also the same error I get back when trying to access the request outside of the app. I used the same headers present in the mobile request as the headers I used in the client.

My wild guess is that I think the app may generate a client-side token that is used to validate where the request is coming from, in order to prevent the request from being made elsewhere. In a sense each request would only be single-use which could be why it works once when analyzing the request in the app, and doesn't work elsewhere.

@chadhurin
Copy link

@idriskhenchil @wannesdemaeght
I was able to get invoice history response off the app without cookies with this endpoint:
POST https://akamai-apigateway-charging-ownership.tesla.com/graphql?deviceLanguage=en&deviceCountry=US&ttpLocale=en_US&vin={vin}&operationName=getChargingHistoryV2

I've seen other "akamai-apigateway-" host prefixes but I searched a while and couldn't find "akamai-apigateway-charging-ownership.tesla.com".

I did not need to add the "x-txid" key to the header (or even the bm_sv cookies).

I hope I'm on the right track and this is helping.

@wannesdemaeght
Copy link
Author

hi @chadhurin
unfortunately it's not working for me. responsestatus is 400 - Bad Request.
accompanying text: {"errors":[{"message":"Oops! Something went wrong. 387be28a-4046-4479-9d86-61bebf6a10cf","txId":"387be28a-4046-4479-9d86-61bebf6a10cf"}]}

I used both POST and GET, with the url you provided, and a working bearer-token...

@chadhurin
Copy link

Hey, @wannesdemaeght
Try this in your body

{ "query": "\n query getChargingHistoryV2($pageNumber: Int!, $sortBy: String, $sortOrder: SortByEnum) {\n me {\n charging {\n historyV2(pageNumber: $pageNumber, sortBy: $sortBy, sortOrder: $sortOrder) {\n data {\n ...SparkHistoryItemFragment\n }\n totalResults\n hasMoreData\n pageNumber\n }\n }\n }\n}\n \n fragment SparkHistoryItemFragment on SparkHistoryItem {\n countryCode\n programType\n billingType\n vin\n credit {\n distance\n distanceUnit\n }\n chargingPackage {\n distance\n distanceUnit\n energyApplied\n }\n invoices {\n fileName\n contentId\n invoiceType\n }\n chargeSessionId\n siteLocationName\n chargeStartDateTime\n chargeStopDateTime\n unlatchDateTime\n fees {\n ...SparkHistoryFeeFragment\n }\n vehicleMakeType\n sessionId\n surveyCompleted\n surveyType\n postId\n cabinetId\n din\n}\n \n fragment SparkHistoryFeeFragment on SparkHistoryFee {\n sessionFeeId\n feeType\n payorUid\n amountDue\n currencyCode\n pricingType\n usageBase\n usageTier1\n usageTier2\n usageTier3\n usageTier4\n rateBase\n rateTier1\n rateTier2\n rateTier3\n rateTier4\n totalTier1\n totalTier2\n totalTier3\n totalTier4\n uom\n isPaid\n uid\n totalBase\n totalDue\n netDue\n status\n}\n ", "variables": { "sortBy": "start_datetime", "sortOrder": "DESC", "pageNumber": 1 }, "operationName": "getChargingHistoryV2" }

with these headers:

--header 'User-Agent: Tesla/1195 CFNetwork/1388 Darwin/22.0.0'
--header 'x-tesla-user-agent: TeslaApp/4.11.1/12ad93c62a/ios/16.0'
--header 'Content-Type: application/json'
--header 'Authorization: Bearer {token}

@chadhurin
Copy link

@wannesdemaeght Did that work?

@wannesdemaeght
Copy link
Author

Hi @chadhurin, thanks for your help!
I got everything working exactly as I wanted.

could you maybe help me along with the correct body to get a list of the premium connectivity invoices?

@wannesdemaeght
Copy link
Author

@chadhurin do you know what endpoint I could use for the premium connectivity invoices, as well as what to put in the body?
Would be a great help!

@andrewdevelopz
Copy link

@chadhurin Hey, do you know if it is possible to get the supercharger location's latitude and longitude from the graphql query from your comment:

#539 (comment)

If so, can you let me know what needs to be added to that query? Thank you.

@thebrrt
Copy link

thebrrt commented May 12, 2023

@idriskhenchil @wannesdemaeght I was able to get invoice history response off the app without cookies with this endpoint: POST https://akamai-apigateway-charging-ownership.tesla.com/graphql?deviceLanguage=en&deviceCountry=US&ttpLocale=en_US&vin={vin}&operationName=getChargingHistoryV2

I've seen other "akamai-apigateway-" host prefixes but I searched a while and couldn't find "akamai-apigateway-charging-ownership.tesla.com".

I did not need to add the "x-txid" key to the header (or even the bm_sv cookies).

I hope I'm on the right track and this is helping.

So this is still working in 2023, but I noticed it no longer returns the invoices for each VIN. It'll instead send a list of the most recent invoices regardless of VIN, but you still need to provide a VIN query parameter or it'll return an error 400.

Is that your experience or am I sending my request incorrectly?

I also noticed invoice.invoices.contentId is null for some invoices. Does this just mean a PDF isn't available to download yet?

@slavikme
Copy link

slavikme commented May 16, 2023

I wonder, what is the query that feeds the graph located in the Charge Stats section in the app?
image

I want to create a periodic charging report (monthly), to include data such as “charge start time”, “charge end time”, “energy consumed”, “location” (home, supercharge, work, other) and the cost, for each vehicle.

Sadly, Tesla do not provide charging data export, so I wonder if it’s possible to retrieve it using the GraphQL query or the REST API? Because, all the data I need does exist in the app.

Thanks!

P.S:
I am JS developer. I would appreciate if someone can send me the obfuscated JS files from the app. I want to try to read them in order to extract as much information as possible.

@superfloh247
Copy link

getChargingHistoryV2 and GetNearbyChargingSites return http 403 since approx 24h

does it still work for you?

@andrewdevelopz
Copy link

andrewdevelopz commented May 24, 2023

@superfloh247 I was getting the same error for getChargingHistoryV2, so I found the invoices from this uri.

https://ownership.tesla.com/mobile-app/charging/history?

Query Params:
vin=%
deviceLanguage=en
deviceCountry=US

Headers:
Authorization: Bearer %

It only returns the 5 most recent invoices and I am not sure how to query for more pages. Would you or anyone else know how?

@thebrrt
Copy link

thebrrt commented May 25, 2023

getChargingHistoryV2 and GetNearbyChargingSites return http 403 since approx 24h

does it still work for you?

Just checked and I too am getting error 403 now ://

@thebrrt
Copy link

thebrrt commented May 25, 2023

@superfloh247 I was getting the same error for getChargingHistoryV2, so I found the invoices from this uri.

https://ownership.tesla.com/mobile-app/charging/history?

Query Params:
vin=%
deviceLanguage=en
deviceCountry=US

Headers:
Authorization: Bearer %

It only returns the 5 most recent invoices and I am not sure how to query for more pages. Would you or anyone else know how?

Thank you for the solution! I implemented it and I got ALL of my invoices since late November of 2022

@andrewdevelopz
Copy link

@superfloh247 I was getting the same error for getChargingHistoryV2, so I found the invoices from this uri.

https://ownership.tesla.com/mobile-app/charging/history?

Query Params:
vin=%
deviceLanguage=en
deviceCountry=US

Headers:
Authorization: Bearer %

It only returns the 5 most recent invoices and I am not sure how to query for more pages. Would you or anyone else know how?

Thank you for the solution! I implemented it and I got ALL of my invoices since late November of 2022

No problem. Did you add any extra query params?

@thebrrt
Copy link

thebrrt commented May 25, 2023

@superfloh247 I was getting the same error for getChargingHistoryV2, so I found the invoices from this uri.

https://ownership.tesla.com/mobile-app/charging/history?

Query Params:
vin=%
deviceLanguage=en
deviceCountry=US

Headers:
Authorization: Bearer %

It only returns the 5 most recent invoices and I am not sure how to query for more pages. Would you or anyone else know how?

Thank you for the solution! I implemented it and I got ALL of my invoices since late November of 2022

No problem. Did you add any extra query params?

No, this is how I make the request:
image

@superfloh247
Copy link

superfloh247 commented May 25, 2023

No, this is how I make the request: image

works for me, but it's incomplete

https://akamai-apigateway-charging-ownership.tesla.com/graphql?deviceLanguage=en&deviceCountry=US&ttpLocale=en_US&vin=" + car.Vin + "&operationName=getChargingHistoryV2"
was paginated and I could poll all supercharger sessions since 2019

the App also loads paginated, I'll play around with URL params :)

@stevemer
Copy link

stevemer commented Jun 1, 2023

What'd you find? @superfloh247

@superfloh247
Copy link

It was a combination of HTTP headers to make it work again

superfloh247/TeslaLogger@f403495

@superfloh247
Copy link

and by "it works" I mean the GraphQL queries, not the GET request

@wannesdemaeght
Copy link
Author

this endpoint works, and is a lot cleaner to implement.
Too bad that there are only 5 invoices generated...

Anyone have an idea on how to get the premium connectivity invoices?
I tried url https://ownership.tesla.com/mobile-app/premium-connectivity/history?vin=5YJ3E7EB9KF48520&deviceLanguage=en&deviceCountry=US but no dice... (VIN spoofed).

@slavikme
Copy link

slavikme commented Aug 26, 2023

I wonder, what is the query that feeds the graph located in the Charge Stats section in the app? image

I want to create a periodic charging report (monthly), to include data such as “charge start time”, “charge end time”, “energy consumed”, “location” (home, supercharge, work, other) and the cost, for each vehicle.

Sadly, Tesla do not provide charging data export, so I wonder if it’s possible to retrieve it using the GraphQL query or the REST API? Because, all the data I need does exist in the app.

Thanks!

P.S: I am JS developer. I would appreciate if someone can send me the obfuscated JS files from the app. I want to try to read them in order to extract as much information as possible.

Found the request! :)

Request

POST https://owner-api.teslamotors.com/api/1/vehicles/{{vehicle-id}}/charge_history?interval={{interval}}&currency_code=ILS&client_country=IL&time_zone=Indian/Mayotte&start_date={{start-date}}&end_date={{end-date}}`

Headers

Authorization: Bearer {{token}}
Content-Type: application/json
x-tesla-user-agent: TeslaApp/4.24.0-1911

Important

x-tesla-user-agent header is important!

Body

You can leave it empty.

Variables

{{vehicle-id}}

Your vehicle ID, that can be retrieved using the https://owner-api.teslamotors.com/api/1/vehicles request.

{{interval}}

Optional. The interval of the records. As far as I know, it supports only the values day and month. If no interval param is provided, day is the default.

{{start-date}}

Optional. The start date from which to show the records.
It should look like this: 2023-07-01T00%3A00%3A00%2B03%3A00.
If start_time is omitted, will return the recent records.

Important

Make sure value is URL encoded.

Note

The resolution of each record, depends on the {{interval}} value.

{{end_date}}

Required if start_date is provided. The start date from which to show the records.
It should look like this: 2023-07-31T00%3A00%3A00%2B03%3A00.

Important

Make sure the value is URL encoded.

{{token}}

You know. Your token in Tesla, generated by OAuth 2.0 protocol.

@aSauerwein
Copy link

this endpoint works, and is a lot cleaner to implement. Too bad that there are only 5 invoices generated...

Anyone have an idea on how to get the premium connectivity invoices? I tried url https://ownership.tesla.com/mobile-app/premium-connectivity/history?vin=5YJ3E7EB9KF48520&deviceLanguage=en&deviceCountry=US but no dice... (VIN spoofed).

hi @wannesdemaeght
i know it has been a long time, but this week I figured out the correct endpoint for Premium Connectivity. It seems like that we also have the same use case "invoices per mail" https://github.com/aSauerwein/tesla-invoices/blob/main/download_v2.py

this is what you need for Premium Connectivity Invoices

hope this helps anyone

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests