CTW Pro · API reference
CTW Pro offers both HTTP and OpenURL interfaces; the two map one-to-one.
| Item | Value |
|---|---|
| HTTP base URL | http://127.0.0.1:8080 |
| OpenURL prefix | CTW://?cmd= |
| Method | GET |
| Result file | /var/mobile/ctwresult.txt |
| Parameter file | /var/mobile/ctwparams.txt |
Return values
HTTP response
HTTP endpoints return JSON directly, for example:
{"version":"1.0.1","code":0}code of 0 means the request succeeded; anything else is an error.
Result file
Long-running operations such as a reset or a record switch require polling /var/mobile/ctwresult.txt for the final outcome:
| Value | Meaning |
|---|---|
0 | Finished |
1 | Error |
2 | Running — keep waiting |
4 | Reached the last record (nextrecord only) |
Note that in the result file 0 means success.
Endpoint list
| Function | HTTP path | OpenURL |
|---|---|---|
| Get the version number | /version | — |
| Launch the app | — | CTW://?cmd=open |
| Reset | /newrecord | CTW://?cmd=newrecord |
| Next record | /nextrecord | CTW://?cmd=nextrecord |
| Clear every record | /deleteallrecords | CTW://?cmd=deleteallrecords |
| Activate a specific record | /activerecord?ID= | CTW://?cmd=activerecord&ID= |
| Activate the first / last record | /activefirstrecord · /activelastrecord | Same cmd names |
| Delete a specific record | /deleterecord?ID= | CTW://?cmd=deleterecord&ID= |
| Import a record directly | /importdirect | CTW://?cmd=importdirect |
| Export a specific record | /exportrecord?ID= | CTW://?cmd=exportrecord&ID= |
| Export every record | /exportallrecords | CTW://?cmd=exportallrecords |
| Rename the current record | /renamecurrentrecord?name= | CTW://?cmd=renamecurrentrecord&name= |
| Look up an ID from a record name | /getbakidfromname?name= | CTW://?cmd=getbakidfromname&name= |
| Get the current record's parameters | /getcurrentrecordparam | CTW://?cmd=getcurrentrecordparam |
| Set the current record's parameters | /setcurrentrecordparam | CTW://?cmd=setcurrentrecordparam |
| Enable / disable an app | /enablerecordapp?bid=&enable= | CTW://?cmd=enablerecordapp |
| Get every record name | /getallrecordsname | CTW://?cmd=getallrecordsname |
| Change the GPS location | /relocationwithbid?x=&y=&z=&r=&bid= | CTW://?cmd=relocationwithbid |
Endpoint details
Get the version number
GET http://127.0.0.1:8080/versionReturns the client version, for example {"version":"1.0.1","code":0}. Useful for checking that CTW is running and the API is reachable.
Launch the app
openURL("CTW://?cmd=open")OpenURL only. Brings CTW Pro to the foreground.
Reset
GET http://127.0.0.1:8080/newrecordGenerates a new device from the current settings and creates a record. Make sure the target apps are ticked inside the app before calling. Poll the result file afterwards — 0 means finished.
Next record
GET http://127.0.0.1:8080/nextrecordSwitches to the next record in the list. When you are already on the last one, the result file returns 4, which is handy for detecting the end of a rotation cycle.
Clear every record
GET http://127.0.0.1:8080/deleteallrecordsWipes every backup record. This cannot be undone.
Activate a specific record
GET http://127.0.0.1:8080/activerecord?ID=XXX| Parameter | Required | Notes |
|---|---|---|
ID | Yes | Record ID. If you only know the record name, get the ID first with Look up an ID from a record name |
Activate the first / last record
GET http://127.0.0.1:8080/activefirstrecord
GET http://127.0.0.1:8080/activelastrecordActivates the first or the last record in the list directly. No parameters needed.
Delete a specific record
GET http://127.0.0.1:8080/deleterecord?ID=XXX| Parameter | Required | Notes |
|---|---|---|
ID | Yes | ID of the record to delete |
Import a record directly
GET http://127.0.0.1:8080/importdirectImports records from /var/mobile/Media/CTWImport/. Zorro backups also go in that folder.
Export a specific record
GET http://127.0.0.1:8080/exportrecord?ID=XXX| Parameter | Required | Notes |
|---|---|---|
ID | Yes | ID of the record to export |
Exports to /var/mobile/Media/CTWExport/.
Export every record
GET http://127.0.0.1:8080/exportallrecordsExports all records to /var/mobile/Media/CTWExport/.
Rename the current record
GET http://127.0.0.1:8080/renamecurrentrecord?name=XXX| Parameter | Required | Notes |
|---|---|---|
name | Yes | New name. Non-ASCII characters must be URL-encoded — see urlEncode in the Lua example below |
Look up an ID from a record name
GET http://127.0.0.1:8080/getbakidfromname?name=XXX| Parameter | Required | Notes |
|---|---|---|
name | Yes | Record name. URL-encode it if it contains non-ASCII characters |
Finds the backup ID for a record name. Commonly used together with activerecord, deleterecord and exportrecord.
Get the current record's parameters
GET http://127.0.0.1:8080/getcurrentrecordparamWrites the current record's device parameters to /var/mobile/ctwparams.txt. See Parameter file for the format.
Set the current record's parameters
GET http://127.0.0.1:8080/setcurrentrecordparamDeprecated
No longer supported after 1.5.2. Do not use this endpoint on newer builds.
Enable / disable an app
GET http://127.0.0.1:8080/enablerecordapp?bid=BUNDLE&enable=1| Parameter | Required | Notes |
|---|---|---|
bid | Yes | Bundle ID of the target app |
enable | Yes | 1 enables, 0 disables |
Get every record name
GET http://127.0.0.1:8080/getallrecordsnameReturns JSON directly:
{
"code": 0,
"data": {
"records": [
{ "id": "...", "name": "...", "selected": true }
],
"count": 1
}
}| Field | Notes |
|---|---|
records[].id | Record ID |
records[].name | Record name |
records[].selected | Whether this is the active record |
count | Total number of records |
Change the GPS location
GET http://127.0.0.1:8080/relocationwithbid?x=&y=&z=&r=&bid=| Parameter | Required | Notes |
|---|---|---|
x | Yes | Longitude |
y | Yes | Latitude |
z | — | Altitude |
r | — | Random offset range |
bid | Yes | Bundle ID of the target app |
Parameter file
Path: /var/mobile/ctwparams.txt
- One parameter per line, separated by
chr(10) - The name and value are separated by a colon
: - Call
getcurrentrecordparamand open the file to see the exact format
| Parameter | Notes |
|---|---|
RecordID | Record ID, e.g. wechat001 |
RecordName | Record name, auto-generated by default |
DeviceName | Device name, e.g. xxxx iPhone |
SystemVersion | iOS version number, e.g. 10.3.1 |
IDFA | IDFA |
IDFV | IDFV |
UDID | Device UDID |
IMEI | Device IMEI |
SerialNum | Device serial number |
MAC | MAC address |
SSID | Wi-Fi network name |
BSSID | Wi-Fi BSSID |
Lua example (TouchSprite)
require "TSLib"
local sz = require("sz")
local http = require("szocket.http")
-- URL encoding (required for non-ASCII record names)
function urlEncode(s)
s = string.gsub(s, "([^%w%.%- ])", function(c)
return string.format("%%%02X", string.byte(c))
end)
return string.gsub(s, " ", "+")
end
-- Poll the result file: true = done / false = error / "last" = reached the final record
function Check_CTW_Result()
::wait::
mSleep(2000)
local f = "/var/mobile/ctwresult.txt"
if isFileExist(f) then
local r = readFileString(f)
if r == "0" then return true end
if r == "1" then return false end
if r == "2" then
toast("in progress", 1)
goto wait
end
if r == "4" then return "last" end
end
end
-- unified call entry point
function CTW(path)
local res, code = http.request("http://127.0.0.1:8080" .. path)
if code == 200 then
return Check_CTW_Result()
end
return false
end
-- Reset
CTW("/newrecord")
-- Switch records by name
local res = http.request("http://127.0.0.1:8080/getbakidfromname?name=" .. urlEncode("wechat001"))
-- After pulling the ID out of res:
CTW("/activerecord?ID=XXX")
-- Rename the current record
CTW("/renamecurrentrecord?name=" .. urlEncode("wechat001"))
-- Walk every record
CTW("/activefirstrecord")
while true do
-- ... your own logic here ...
if CTW("/nextrecord") == "last" then break end
end
-- OpenURL form
openURL("CTW://?cmd=open")
openURL("CTW://?cmd=newrecord")For usage, see the CTW Pro user guide.
The interface and supported systems may change with updates. Back up important data before cleaning, resetting or deleting anything.
