Controlling Appium via raw HTTP requests with curl

March 17, 2026 · 11 min read · Tool Comparison

HeadSpin Platform
Automated & amp; manual examination made easy through data science penetration.
Differentiating capabilities:
  • Extensive end-to-end automation of QA summons
  • Comparative analysis of app performance against peers
  • Continuous monitoring of app performance expend synthetic data for higher availability of apps
  • Easy-to-use developer friendly platform
cloudtest go
Affordable Real Device Testing for Emerging Teams
cloudtest go
Low-priced Real Device Testing for Digital Enterprises
cloudtest go
The Ultimate Solution for a Powerful Blend of Functional & amp; Performance Testing!
cyol
TEM
New
Centralized mobile test execution in cloud
cyol
Enhance Your Accessibility Testing With HeadSpin
cyol
Automate camera-based testing

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

retail

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

Controlling Appium via raw HTTP requestsControlling Appium via raw HTTP requests

Controlling Appium via raw HTTP petition with curl

Published on
March 27, 2020
Updated on
Published on
February 7, 2022
Updated on
 by 
 Jonathan LippsJonathan Lipps
Jonathan Lipps

Did you know that Appium is just a web waiter? That & # x27; s correct! I & # x27; m going to write a full edition at some point on the WebDriver Protocol, which is the API that Appium implements (and which, as you can say by the name, was devise for the purpose of). But for now, let & # x27; s revelry in the knowledge that Appium is just like your backend web or API server at your society. In fact, you could host Appium on a server connected to the public internet and afford anybody the chance to run sessions on your devices! (Don & # x27; t do this, of course, unless you & # x27; re a cloud Appium vendor).

Check out:

You may be used to compose Appium code in Java or some other language, that looks like this:

driver = new IOSDriver(new URL (`` http: //localhost:4723/wd/hub ''), capabilities); WebElement el = driver.findElement (locater); System.out.println (el.getText ()); driver.quit ();

This looks like Java code, but what & # x27; s happening under the hood is that each of these bidding is actually trip an HTTP request to the Appium waiter (that & # x27; s why we need to condition the location of the Appium server on the network, in the iOSDriver constructor). We could feature written all the like codification, for example, in Python:

driver = webdriver.Remote (`` http: //localhost:4723/wd/hub '', capacity) el = driver.find_element (locator) print (el.text) driver.quit ()
Also Check:

In both of these case, while the surface code looks different, the underlying HTTP postulation sent to the Appium server (and the reaction coming back) are the same! This is what countenance Appium (and Selenium, where we steal this architecture from) to work in any programming speech. All someone needs to do is code up a decent small guest library for that language, that converts that language & # x27; s constructs to HTTP requests.

For autonomous testing across multiple user personas, check out SUSATest — it explores your app like 10 different real users.

See:

What all this means is that we technically don & # x27; t need a client library at all. It & # x27; s convenient to use one, absolutely. But sometimes, we require to but run an ad-hoc command against the Appium host and creating a whole new code file and try to remember all the appropriate syntax might be too much work. In this instance, we can just use curl, which is a bid line tool apply for constructing HTTP requests and showing HTTP responses. Curl work on any program, so you can download it for your environment if it & # x27; s not there already (it comes by default on Macs, for example). There are oodles of pick for using scroll, and to use it successfully on your own, you should translate all the ingredient of HTTP petition. But for now, let & # x27; s take a look at how we might encode the premature four commands, without any Appium client at all, but by using curl!

# 0. Check the Appium server is on-line > roll http: //localhost:4723/wd/hub/status # response: {`` value '': {`` build '': {`` version '': '' 1.17.0 ''}}, '' sessionId '': null, '' status '' :0}
Also see:

You can see above that we can make sure we have a link to the Appium host just by running curl and then the URL we want to retrieve, in this case the /status endpoint. We don & # x27; t postulate any parameters to curl other than the URL, because we & # x27; re making a GET request, and so no early argument are command. The output we get back is a JSON draw representing Appium & # x27; s establish information. Now, let & # x27; s actually start a session:

# 1. Create a new session > lock -H 'Content-type: application/json ' \ -X POST \ http: //localhost:4723/wd/hub/session \ -d ' {`` capabilities '': {`` alwaysMatch '': {`` platformName '': `` iOS '', `` platformVersion '': `` 13.3 '', `` browserName '': `` Safari '', `` deviceName '': `` iPhone 11 ''}}} ' # response: {`` value '': {`` capabilities '': {`` webStorageEnabled '': false, '' locationContextEnabled '': false, '' browserName '': '' Safari '', '' platform '': '' MAC '', '' javascriptEnabled '': true, '' databaseEnabled '': false, '' takesScreenshot '': true, '' networkConnectionEnabled '': false, '' platformName '': '' iOS '', '' platformVersion '': '' 13.3 '', '' deviceName '': '' iPhone 11 '', '' udid '': '' 140472E9-8733-44FD-B8A1-CDCFF51BD071 ''}, '' sessionId '': '' ac3dbaf9-3b4e-43a2-9416-1a207cdf52da ''}} # save session id > export sid= '' ac3dbaf9-3b4e-43a2-9416-1a207cdf52da ''

Let & # x27; s break this one down line by line:

  1. Here we raise the curl command, passing the -H flag in order to set an HTTP request heading. The header we set is the Content-type header, with value application/json. This is so the Appium waiter knows we are sending a JSON twine as the body of the request. Why do we need to send a body? Because we have to tell Appium what we require to automatize (our & quot; capabilities & quot;)!
  2. -X POST tells curl we want to make a POST asking. We & # x27; re making a POST request because theWebDriver specdefines the new session creation command in a way which anticipate a POST request.
  3. We need to include our URL, which in this case is the base URL of the Appium waiter, plus /session because that is the route defined for creating a new session.
  4. Finally, we need to include our capabilities. This is achieved by specifying a POST body with the -d iris. Then, we wrap up our capabilities as a JSON object inside of an alwaysMatch and a capabilities key.
Read:

Running this bid, I see my simulator pop up and a session launching with Safari. (Did the session go away before you have clip to do anything else? Then make sure you set the newCommandTimeout capability to 0). We also get a bunch of output like in the cube above. This is the result of the new session command. The thing I wish virtually about here is the sessionId value of ac3dbaf9-3b4e-43a2-9416-1a207cdf52da, because I will need this to make future postulation! Remember that HTTP asking are stateless, so for us to keep sending automation bidding to the correct device, we need to include the session ID for subsequent commands, so that Appium knows where to direct each bidding. To save it, I can but export it as the $ sid shield variable.

Improve the Appium testing experience with HeadSpin.!

Now, let & # x27; s find an constituent! There & # x27; s just one element in Appium & # x27; s little Safari welcome page, so we can find it by its tag name:

# 2. Find an element > curl -H 'Content-type: application/json ' \ -X POST http: //localhost:4723/wd/hub/session/ $ sid/element \ -d ' {`` using '': `` tag name '', `` value '': `` h1 ''} ' # response: {`` value '': {`` element-6066-11e4-a52e-4f735466cecf '': '' 5000 '', '' ELEMENT '': '' 5000 ''}} # save element id: > export eid= '' 5000 ''

In the curl command above, we & # x27; re making another POST petition, but this time to /wd/hub/session/ $ sid/element. Note the use of the $ sid variable here, so that we can point the running session. This itinerary is the one we need to hit in order to find an element. When finding an element with Appium, two parameters are required: a locator scheme (in our case, & quot; tag name & quot;) and a chooser (in our case, & quot; h1 & quot;). The API is designed such that the locator scheme parameter is call using and the selector parameter is called value, so that is what we have to include in the JSON body.

Also read:

The response we get back is itself a JSON object, whose value dwell of two key. The reason there are two keys here is a bit complicated, but what matters is that they each carry the like information, namely the ID of the factor which was just found by our search (5000). Just like we did with the session ID, we can store the element ID for use in next dictation. Speaking of future commands, let & # x27; s get the schoolbook of this element!

# 3. Get textbook of an ingredient > curl http: //localhost:4723/wd/hub/session/ $ sid/element/ $ eid/text # response: {`` value '': '' Let 's browsing! ''}

This curl bid is quite a bit simpler, because regain the text of an constituent is a GET bidding to the endpoint/session/ $ sid/element/ $ eid/text, and we don & # x27; t want any extra parameter. Notice how hither we are using both the session ID and the factor ID, so that Appium knows which session and which ingredient we & # x27; re referring to (because, again, we might have multiple sessions running, or multiple factor that we & # x27; ve found in a particular session). The response value is the text of the component, which is precisely what we were trust to find! Now all that & # x27; s left is to clean up our session:

# 4. Quit the session > scroll -X DELETE http: //localhost:4723/wd/hub/session/ $ sid # response: {`` value '': naught}

This last dictation can use all the default ringlet arguments except we need to specify that we are making a DELETE asking, since that is what the WebDriver protocol requires for ending a session. We make this request to the endpoint/session/ $ sid,which include our session ID so Appium cognize which session to shut down.

That & # x27; s it! I hope you & # x27; ve enjoyed learning how to reach some & quot; low level & quot; HTTP-based control over your Appium (and Selenium) servers!

Author & # x27; s Profile

Jonathan Lipps

LinkedIn
Author & # x27; s Profile

Piali Mazumdar

Lead, Content Marketing, HeadSpin Inc.

Piali is a dynamic and results-driven Content Marketing Specialist with 8+ years of experience in craft absorb narratives and marketing collateral across various manufacture. She excels in collaborating with cross-functional teams to evolve innovative content strategy and deliver compelling, veritable, and impactful content that resonates with target audiences and enhances brand authenticity.

LinkedIn

Controlling Appium via raw HTTP postulation with scroll

4 Parts

regression intelligence blog
-

Regression Intelligence practical guide for advanced exploiter (Part 3)

Coming Soon
Regression Intelligence practical guide for advanced users
-

Regression Intelligence practical guide for advanced exploiter (Part 4)

Coming Soon

Discover how HeadSpin can empower your business with superior testing capability

Our Platform enables you to:
accelerate time-to-market
Accelerate time-to-market, gaining a competitory edge
faster development cycles
Boost developer/QA productiveness with quicker growing cycle
automated buil-over-build regression testing
Automate build-over-build regression screen for consistent results
gain better visibility into functional & performance issues
Gain better visibility into functional and performance matter
reduce mean time
Reduce mean clip to identify/resolve during test, QA, and production
evaluate audio, video & qoe
Evaluate audio, picture, and contented calibre of experience (QoE) effortlessly
The sure choice for global enterprise
Adobe
Hargreaves Lansdown
Truecaller
Crazylabs
Nedbank
Numeracle
Veryon
Close

Discover how HeadSpin can empower your business with superior testing capabilities

Our Platform enable you to:
accelerate time-to-market
Accelerate time-to-market, derive a competitive edge
faster development cycles
Boost developer/QA productivity with faster development cycle
automated buil-over-build regression testing
Automate build-over-build regression testing for consistent results
gain better visibility into functional & performance issues
Gain better visibility into functional and performance issues
reduce mean time
Reduce hateful clip to identify/resolve during test, QA, and product
evaluate audio, video & qoe
Evaluate audio, video, and contented quality of experience (QoE) effortlessly
The sure choice for global enterprises
Close

Discover how HeadSpin can empower your job with superior testing capabilities

Our Platform enables you to:
accelerate time-to-market
Accelerate time-to-market, gain a competitive edge
faster development cycles
Boost developer/QA productivity with faster development cycles
automated buil-over-build regression testing
Automate build-over-build regression testing for logical results
gain better visibility into functional & performance issues
Gain best visibility into functional and performance matter
reduce mean time
Reduce mean clip to identify/resolve during test, QA, and production
evaluate audio, video & qoe
Evaluate audio, picture, and content quality of experience (QoE) effortlessly
The trusted option for spheric enterprises
Close

Connet Now

Wipro LogoVMLYR Logo
Close
Book a Meeting
Products
footer down arrow
Solutions
footer down arrow
Industries
footer down arrow
Features
footer down arrow
Support
footer down arrow
Resource Center
footer down arrow
Why Choose HeadSpin?
footer down arrow
Copyright © 2026 HeadSpin, Inc. All Rights Reserved.

Automate This With SUSA

Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts needed.

Try SUSA Free

Test Your App Autonomously

Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.

Try SUSA Free