app.http - HTTP Request API

Send HTTP/HTTPS requests.

Note: When called within a coroutine created by app.thread.create, requests are automatically executed asynchronously, transparent to the caller.

Methods

app.http.get(url, headers?)

Send a GET request.

Parameters:

  • url (string) - Request URL
  • headers (table, optional) - Request header key-value pairs

Returns: table, error

  • status (number) - HTTP status code
  • body (string) - Response body
  • headers (table) - Response header key-value pairs
local response = app.http.get("https://api.example.com/data")
if response and response.status == 200 then
    local data = app.json.parse(response.body)
end

-- With request headers
local response = app.http.get("https://api.example.com/data", {
    ["Authorization"] = "Bearer token123",
    ["Accept"] = "application/json"
})

app.http.post(url, data, headers?)

Send a POST request.

Parameters:

  • url (string) - Request URL
  • data (string|table) - Request body (string or table)
    • String: used directly as the request body
    • Table: automatically serialized to JSON with Content-Type set accordingly
  • headers (table, optional) - Request header key-value pairs

Returns: table, error - Same as GET

-- Send JSON
local response = app.http.post("https://api.example.com/users", {
    name = "John",
    email = "john@example.com"
})

-- Send raw string
local response = app.http.post("https://example.com/data", "raw body content", {
    ["Content-Type"] = "text/plain"
})

app.http.request(config)

Generic HTTP request method with support for custom methods, timeouts, redirect control, etc.

Parameters:

  • config (table):
    • url (string, required) - Request URL
    • method (string, optional) - HTTP method (default "GET")
    • headers (table, optional) - Request header key-value pairs
    • body (string|table, optional) - Request body (tables are automatically serialized to JSON)
    • timeout (number, optional) - Timeout in seconds
    • followRedirects (boolean, optional) - Whether to follow redirects (default true)

Returns: table, error - Same as GET

-- PUT request
local resp, err = app.http.request({
    url = "https://api.example.com/users/1",
    method = "PUT",
    headers = {["Authorization"] = "Bearer token123"},
    body = {name = "New Name"},
    timeout = 30
})

-- DELETE request
local resp, err = app.http.request({
    url = "https://api.example.com/users/1",
    method = "DELETE"
})

-- Without following redirects
local resp, err = app.http.request({
    url = "https://example.com/redirect",
    followRedirects = false
})
if resp then
    app.log.info("Status: " .. resp.status)  -- Could be 301/302
end

app.http.download(url, savePath, headers?)

Download a file to the specified path.

Parameters:

  • url (string) - Download URL
  • savePath (string) - Save path
  • headers (table, optional) - Request header key-value pairs

Returns: boolean, error

local ok, err = app.http.download(
    "https://example.com/file.zip",
    "/path/to/save/file.zip"
)

if ok then
    app.notification.show("Download Complete", "File has been saved")
else
    app.log.error("Download failed: " .. (err or ""))
end

-- With custom headers
local ok, err = app.http.download(
    "https://example.com/file.zip",
    "/path/to/save/file.zip",
    {["Authorization"] = "Bearer token123"}
)

app.http.upload(url, config)

Upload a file (multipart/form-data).

Note: When called within a coroutine created by app.thread.create, the upload is automatically executed asynchronously.

Parameters:

  • url (string) - Upload URL
  • config (table):
    • file (string) - File path (required)
    • fieldName (string, optional) - Form field name, default "file"
    • fileName (string, optional) - File name, defaults to the name extracted from the path
    • mimeType (string, optional) - MIME type, auto-detected by default
    • fields (table, optional) - Additional form fields
    • headers (table, optional) - Request headers
    • method (string, optional) - HTTP method, default "POST"
    • timeout (number, optional) - Timeout in seconds, default 60

Returns: table, error

  • status (number) - HTTP status code
  • body (string) - Response body
  • headers (table) - Response headers
-- Simple upload
local resp, err = app.http.upload("https://api.example.com/upload", {
    file = "/path/to/photo.jpg"
})

-- With additional fields
local resp, err = app.http.upload("https://api.example.com/upload", {
    file = "/path/to/document.pdf",
    fieldName = "attachment",
    fields = {
        title = "My Document",
        category = "report"
    },
    headers = {
        ["Authorization"] = "Bearer token123"
    }
})

if resp and resp.status == 200 then
    app.notification.show("Upload Successful", "File has been uploaded")
end

Examples

Call a REST API

function MyPlugin:fetchGitHubRepo(owner, repo)
    local url = string.format("https://api.github.com/repos/%s/%s", owner, repo)

    local response = app.http.get(url, {
        ["Accept"] = "application/vnd.github.v3+json",
        ["User-Agent"] = "iRightMenu-Plugin"
    })

    if not response or response.status ~= 200 then
        app.log.error("Request failed: " .. (response and response.status or "network error"))
        return nil
    end

    return app.json.parse(response.body)
end

Download a File

function MyPlugin:handleDownload(context)
    local url = "https://example.com/file.zip"
    local filename = app.path.basename(url)
    local savePath = app.path.join(context.currentDirectory, filename)

    if app.http.download(url, savePath) then
        app.notification.show("Download Complete", filename)
        app.finder.reveal(savePath)
    else
        app.notification.show("Download Failed", "Unable to download file")
    end
end

Using in Coroutines (Async)

function MyPlugin:handleFetchData(context)
    app.thread.create(function()
        -- Inside a coroutine, HTTP requests are automatically async
        local response = app.http.get("https://api.example.com/data")

        if response and response.status == 200 then
            local data = app.json.parse(response.body)
            app.notification.show("Success", "Fetched " .. #data .. " records")
        end
    end)
end
Developer Documentation
User Guide
Getting Started Script Menus FAQ
Script Development
Development Guide
Plugin Development
Quick Start Development Guide Example Plugins
API Reference
Overview API Query Plugin Info Logging Finder Context Plugin Settings Internationalization
UI & Interaction
Dialog Progress Notification Chooser WebView Status Bar Dock
Files & Paths
File Operations Path Utilities Finder Actions Trash Extended Attributes Metadata File Watcher
Data Formats
JSON Plist CSV XML PDF Image
Text & Encoding
String Regex Date & Time Color Crypto
System
Shell Commands Process Application System Info AppleScript Shortcuts
System Info
Network Power/Battery Screen/Appearance Audio Bluetooth Location
Network
HTTP WebSocket URL
Input & Clipboard
Keyboard Mouse Hotkey Clipboard Window
Storage
SQLite Keychain UserDefaults
Media
OCR QR Code
Utilities
Archive UTI Share Timer Wake Lock Thread