surge_confirmation_id changes between requests - uber-api

I am making two requests to the Uber API in a row.
POST /v1/requests/estimate
POST /v1/requests
The first to get an estimate and the second to make the ride request. When I get the estimate I am getting a value for surge_confirmation_id. I send this value as a parameter of the same name when making the request to the API for creating a ride request.
The response from Uber on the second request is a 409 error, saying that there is surge pricing in effect and providing me with a different surge_confirmation_id than what was provided in the estimate.
I have run this test about 7 times and the surge_confirmation_id is always different between the first and second request. Any idea what I am doing wrong, or whether this is expected behavior? It doesn't make sense that the surge estimate would always be wrong or change so quickly (we are talking 5 seconds between the two requests).
Side note, the /v1/requests/estimate endpoint is the only endpoint which returns the surge multiplier as a number. Calling /v1/requests will only return a URL to show the surge confirmation. This is not acceptable for me because I am coding a voice-based service which does not allow me to show any UI.

Estimates is only for you to estimate the price and trip.
You should present the received url by some ways since the url would load a website for customer to accept or deny the surge price.
Once customer accepts it then you can pass the surge_confirmation_id back to Uber.

Related

How would you design a REST API that includes the simulation of a POST?

For ex. I need to design an API with two features: payment validation and payment creation.
I need both because the end user should know that everything is ok before actually confirm the payment creation.
For creation I have
POST .../payment
with an input body. It returns HTTP 400 in case something went wrong.
The validation (or simulation) does the exact same process than the creation, stopping the process just before persisting the data. For this validation, is it better to have something like
Solution 1
GET .../is-payment-ok
also with an input body. It returns HTTP 200 including a boolean answer and some details.
Here the resource is not the payment, it's the information about the validity of the payment, which seems REST-compliant to me. The drawback being that the user of the API could be confused because if the payment is not valid, then the simulation would return HTTP 200 (with the boolean in the body set to false) while the creation would return HTTP 400.
, or
Solution 2
POST .../payment?simulation=true , or
POST .../payment-simulation
Here the HTTP response code would be exactly the same as for a payment creation. The drawback being that we use a POST, without actually 'posting' any resource.
How would you do it ? Is there a REST rule or common practice for this case ?
While not strictly forbidden, GET requests usually have no request bodies: HTTP GET with request body, so I would not go with Solution 1.
In our APIs (Payment APIs too) we use a query param with the same URL to flag a dry-run (or forecast in our domain terms), just like your Solution 2, and as described here: Dry run strategy for REST API. It gives back the same error codes and messages that non-forecast requests would yield in case of an error.
We needed this due to we use a reactive payment processor, but it only starts if the payment-forecast succeeded. The process give back this forecast result as a response to the user immediately after the process starts, increasing the responsivity of the UI. The actual payment will take a second to be sent for real processing, as some checks are done reactively with other services. It may even fail and the end-user will get a notification about the final status, but this will be very rare.
If you check the HTTP spec, how POST processes a resource is pretty arbitrary, there is no need to make a persistent change in anything: https://www.rfc-editor.org/rfc/rfc7231#section-4.3.3
The POST method requests that the target resource process the
representation enclosed in the request according to the resource's
own specific semantics
[...]
If one or more resources has been created on the origin server as a
result of successfully processing a POST request, the origin server
SHOULD send a 201 (Created) response containing a Location header
field that provides an identifier for the primary resource created
(Section 7.1.2) and a representation that describes the status of the
request while referring to the new resource(s).
Just make sure to document the query param. EDIT: Kubernetes does it: https://kubernetes.io/docs/reference/using-api/api-concepts/#dry-run
The Stripe API is a bit different since if you send a request it will be booked, there is no dry-run (the /capture call is called by the money requester, not the payer, so it is another use-case).
I would suggest you to create 2 endpoints, this is commonly done among payment service providers like UsaEPay,Stripe,etc.
The first endpoint will be something like: POST .../authorize and will receive all the information needed to make the payment such as the amount, payer info and payment method info, then it will create a paymentAuthorization and return the status of it among with an authorizationToken if the authorization succeeded.
The second endpoint will be something like: POST .../capture, in this endpoint you will only look for the paymentAuthorization related to the authorizationToken you generated before and proceed to make the payment
Also you could take a look a the Stripes documentation https://stripe.com/docs/api/payment_intents to understand more about this kind of system structure
I agree with the other answers for using your option 2 with two endpoints to reduce ambiguity.
You use the term validation in your question, and I believe it relays what is going on better than simulation. I would expect a simulation call return the same response as the payment, but not allow the payment to go through.
A validation request would more intuitively let the user know that the API would evaluate the request and at the very least tell you if it was acceptable or not.
Option 1 would go against standard design principles, as a GET request typically has the body ignored if it exists.
Follow your domain's uri path design, or use some of the resources mentioned in the other answers.
POST .../Payment
POST .../Validate/Payment
Depending what type of payments you're working with, you may be interested in a two-phase commit approach. This also aligns more with the REST interface than the RPC-like "is this ok" call.
The idea here is that you create one resource (let's call it the payment authorization, POST /payment-authorizations) which ensures all resources are available, in this case putting a hold on the user's account for the amount of the payment, and returning the id of the new payment.
Now the user can review the payment (GET /payment-authorizations/{id}).
They can cancel it if they want (DELETE /payment-authorizations/{id}), releasing the funds.
Or they can finalize it (PUT /payments/{id}).
The main advantages of this approach are that
It's RESTfull
Payments are idempotent (you can try to finalize a payment as many times as you want, but it will only ever send the money once)
The payment validation step is ACTUALLY USEFUL
Elaborating more on that last item: these API calls you're making are asynchronous, and race conditions are fully possible. You could have a scenario like
Alice Alice's Account Chuck
$10
"can I send $5 to Bob?" ->
<- "yes"
<- "can I withdraw $6 for rent?"
"yes" ->
<- "withdraw $6 for rent"
"ok" ->
$4
"send $5 to Bob" ->
<- "insufficient funds"
Now your client is confused, the system said it could make a payment, but it can't. With a two-phase commit you'd have
Alice Alice's Account Chuck
$10
"authorize $5 to Bob" -> "ok, authz #5"
$5(+5)
<- "authorize $6 for rent"
"insufficient funds" ->
"send payment #5" -> "ok"
$5
Now Alice is still broke, but all the responses we've given are accurate.
As i can see, you are interested in URI Path Design.
Usually:
Singular Nouns are used as to refer a single document resourse into your URL.
Plural Nouns are used to refer to a collections or stores.
Verrbs represent actions, which can be considered as a controller, like Validate or Store.
In REST, a request of type POST can be used to create a new resource into a collection or execute a controller. So, using Post seems to be a correct choice for your API.
Now, in your case, you need to perform two actions Create and Validate:
In your case, i would create two possible URL, one for create a Payment and another one to validate it, sending an Id of the payment.
POST .../Create/Payment
POST .../Simulate/Payment/{IdPayment}
I considered Payment as a single document and Create and Simulate as a controller. In the case of Simulate, i adding am Id to the Payment document to identify it.
There is a book, from O'Reilly, which is easy to read and has all the information that you are looking for. This book is REST API Design Rulebook
I hope this information could be helpful for you.

Limit for REST API Calls towards Dropbox?

Is there a fix number for REST Calls towards Dropbox like 1000 requests per Day etc.
I cant find any Information on the Dropbox site.
Thank you!
The Dropbox API does have a rate limiting system, but there aren't any specific numbers documented. The limits operate on a per-user basis.
Also note that not all 429s and 503s indicate rate limiting, but in any case that you get a 429 or 503 the best practice is to retry the request, respecting the Retry-After header if given in the response, or using an exponential back-off, if not.

Uber sandbox api returns duplicate ride request id for mutiple ride requests

I have created a session with sandbox_mode = True, with all scopes, including request, using uber_rides python library. The api calls work fine, but I get duplicate request_ids for mutiple ride requests(fired one after the other, and not concurrent). Though these requests are using the same lat, longs and product_id. Can it be possible that uber creates a ride id using lat, long ?
Is this okay ? Or am I actually missing something, and this should never happen ?
I think the issue you might be running into is that if you are already on a trip and you try to create a new one, the API will just return the trip details for your current trip. So I think what is happening is you're creating one trip, then trying to create another and you're getting back a "processing" status so it looks like you created a new trips, but its actually still the first trip.
You can verify this by creating a trip, checking the UUID, canceling the trip, then requesting a new one and seeing if the UUID is different.
Best,
Riche
product_id is based on the start_latitude/start_longitude or start_place_id parameters.
request_id is not (it's just a UUID identifying the ride request)
If you are doing multiple ride requests with the same OAuth Bearer token and you do not cancel the first ongoing ride request you are basically getting back the status details of the current ongoing trip.
According to Uber Help - CAN I REQUEST MORE THAN ONE UBER?
At this time, it’s not possible to request more than one ride from a
single account.
If your party cannot be accommodated by a single vehicle, have
multiple people in your group request rides. We offer vehicle options
accommodating up to 6 people in many cities.
If no one else in your group has an Uber account, you can invite them
to sign up from the main menu of your app. As a bonus, both you and
your friend will receive the referral promotion.
This also applies to the Uber API.
However, from my use of the Uber API I've noticed the following rate limiting headers sent back on some responses:
X-Rate-Limit-Limit-Concurrent-Trips: 10
X-Rate-Limit-Remaining-Concurrent-Trips: 10
so they probably plan to add the possibility of making concurrent ride requests from the same Uber rider.

Facebook GraphAPI Reduce amount of data with limit

So I'm struggling to find where this is documented (if at all), but I'm getting the following error message when requesting data from the FB GraphAPI.
"Please reduce the amount of data you're asking for, then retry your request"
The call I'm making is:
/v2.3/user1/posts?fields=object_id&limit=100
If I change it to:
/v2.3/user2/posts?fields=object_id&limit=100
It returns 100 items.
Why would it work for one user, and not the other?
Both requests are authenticated via an access token (not belonging to either user) and I get the same error whether running it from my code, or the Facebook Graph API console of developers.facebook.com
The response from CBroe is correct. Facebook returns this error if it finds that too many internal resources are needed to respond to your request.
Therefore you have to do what the response says: limit it.
This can be done in (afaik) 2 ways:
Use the limit parameter and reduce the amount of responses you expect from the API
Provide a timeframe (using since and / or until) to fetch only data (posts / videos) for a specific timeframe.
We had the same issue as you, but with retrieving videos from a page. Unfortunately using the limit parameter did not work, even when I set it to limit=1. But by using the since / until parameters we finally got results.
Therefore I suggest to implement a timeframe in order to reduce the amount of data, or alternatively, split the amount of requests you make. e.g. if you want all posts from the past 3 months and run into the mentioned error: split your requests in half using since and until. If that still does not work: keep splitting...
=> Divide and conquer ;)
Hope it helps,
KR, ebbmo
Recent bug filed on FB talks about the same error. They seem to accept that this could be a bug, but not much other information forthcoming.
https://developers.facebook.com/bugs/1904674066421189/
There are both app-level and user-level rate limits that are enforced on Graph API calls. In your case, it could be that you've made a large number of calls in a short time with user1.
You can check out this page for more about Facebook's rate limits: https://developers.facebook.com/docs/marketing-api/api-rate-limiting (even though the URL refers to the Marketing API, the information also applies to the Graph API.)

Bing Maps REST api - Where can I find more detailed information concerning error messages?

I've already checked out their page on error handling but all it has is descriptions of the status codes a request may return. Does bing provide information one what will be returned if I have exceeded the number of requests allowed per day?
If you have exceeded the number of request per day, there might be an information included in your response header. It must fit with the limitations described in the terms of use.
See at the bottom of the page you linked, tell us what you got from here:
Responses that do not return results
Occasionally, the servers processing service requests can be
overloaded, and you may receive some responses that contain no results
for queries that you would normally receive a result. To identify this
situation, check the HTTP headers of the response. If the HTTP header
X-MS-BM-WS-INFO is set to 1, it is best to wait a few seconds and try
again.