Cloud browsers, mobile devices and computers from TypeScript, Go and Python.
Verify is a TypeScript, Go and Python library for Revyl. Open a cloud browser, iOS simulator or Android emulator for natural-language instructions and validations, or an early-access Mac/Linux computer for commands, files, processes and screenshots. Call it from a script, coding agent or your existing test runner.
Run these from the project's directory with Node.js ≥22.18. The authentication command requires the Revyl CLI; if REVYL_API_KEY is already supplied securely, skip login.
npm install --save-dev @revyl/verify
npx @revyl/verify init --platform ios
revyl auth login
npx @revyl/verify whoamiIf login prints an approval URL, share it privately with the user so they can approve it in their browser. For unattended runs, supply REVYL_API_KEY through a secret manager; never put credentials in argv, source or logs. Configure the generated verify.config.ts before running node verify/example.ts. Starting a cloud session requires an authorized account and workload.
Use Node.js ≥22.18:
npm install --save-dev @revyl/verifyThe unscoped revyl-verify package is an alias with the same API and CLI, for example npx revyl-verify init --platform ios.
Use Go ≥1.26.9 in an existing Go module:
go get github.com/RevylAI/verify/go@v0.1.0Go releases use independent go/v* tags; npm versions do not version the module. Keep the generated go.mod and go.sum to pin dependencies. The SDK uses only the standard library.
Use Python ≥3.10. Python 0.1.0 is prepared in source, not published to PyPI yet. From a reviewed repository checkout, install it into an active virtual environment:
uv pip install ./pythonThe distribution is revyl-verify; import revyl_verify. See the Python SDK source guide for sync/async APIs, computer examples, and package validation. Python behavior is covered by fake-server tests, not live Revyl verification.
All SDKs use this credential order:
- A usable stored CLI login marked
local_auth_override. REVYL_API_KEYfrom the environment.- Another usable CLI login stored by
revyl auth login.
An expired access token can fall back to its stored API key. Set environment keys through a secret manager, or sign in interactively:
revyl auth loginSee configuration for credential and endpoint options.
Run npx @revyl/verify init --platform ios. For this Settings example, replace the generated app block with app: { bundleId: 'com.apple.Preferences' }. Save the following as verify/example.ts and run node verify/example.ts. For your own uploaded app, set app.appId and adapt the steps.
import { open } from '@revyl/verify';
const session = await open('ios');
try {
await session.instruction('Open General, then About');
await session.validation('The screen shows the operating system version');
} finally {
await session.close();
}For web, use init --platform web with a Revyl web app ID and public HTTPS URL. See getting started.
Inside a function returning error, with a bounded ctx and imports for context, time, and verify "github.com/RevylAI/verify/go":
session, err := verify.Open(ctx, verify.Target{Platform: verify.IOS, BundleID: "com.apple.Preferences"})
if err != nil {
return err
}
defer func() {
cleanup, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
_ = session.Close(cleanup)
}()
if _, err := session.Instruction(ctx, "Open General, then About"); err != nil {
return err
}
_, err = session.Validation(ctx, "The screen shows the operating system version")
return errThis sketch ignores cleanup errors; the complete Go examples handle them. Go has no process-exit handlers. TypeScript's automatic cleanup is best effort, bounded to 15 seconds, and skips signal/error handlers that already have listeners. Always close explicitly: device close acknowledges a stop request; computer close requires terminal state and confirmed release.
from revyl_verify import Target, open
with open(Target(platform="ios", bundle_id="com.apple.Preferences", start_timeout=600)) as session:
session.instruction("Open General, then About", timeout=120)
session.validation("The screen shows the operating system version", timeout=120)
session.screenshot(path="settings.png")All Python timeout values are seconds. For asyncio, use async with await async_open(Target(...)) and await the session methods; see the Python source guide. Context managers close sessions even when a step raises. The Python SDK has no bundled CLI or test runner.
| Platform | Instructions / validations | Commands / files / processes | PNG screenshot | Availability |
|---|---|---|---|---|
| Web | Yes | — | Yes | Production; selected backend must support web steps |
| iOS simulator | Yes | — | Yes | Production |
| Android emulator | Yes | — | Yes | Production |
| Mac computer | — | Yes | Yes | Early access; contact support |
| Linux computer | — | Yes | Yes | Early access; contact support |
Computers are early access; ask support@revyl.ai about access. They have a hard 60-minute lifetime from create. Mac supports init --platform mac; Linux init is unavailable, so use open({ platform: 'linux' }) or a config target. See computers.
- Documentation index · API · CI · Coding agents
- End-to-end results and limitations
- Examples: Web store · Mobile Settings · Mac workspace · Go · Python source
- Contributing · Security · Releasing
NOT_AVAILABLE_ON_PLATFORM: computer agent steps and device command/file methods are unavailable. Computer access is controlled by Revyl; web steps need backend support. Check the platform contract.COMPUTER_LIMIT: admission was refused because of queued work or a concurrency limit. Wait for capacity; Verify does not retry creation or stop a definitely refused start.- Blank first screen: mobile startup makes a bounded, best-effort blank-frame observation, not a rendered/foreground-readiness guarantee. Begin with an instruction that reaches the screen you need. Computer capture retries structured startup screen-not-ready responses for a fixed 30-second window; Linux screenshot retry is tests-only, not proven live.
- A report's counters look successful but validation failed: inspect
effective_status,validation_resultandvalidations_passedagainsttotal_validations, not transport counts. Failed SDK validations throw by default. See reading the verdict.