GET STARTED ON YOUR OWN SERVER
Deployment and
licensing guide
Use your cameras with an edge server that processes footage locally. This guide covers camera registration, commercial licence activation and local deployment, with separate instructions for sandbox evaluations.
Updated 30 October 2026 · PowerShell 7 examples on a Linux server · Licensed CPU Docker runtime
Your deployment journey
Five steps from planning to operation. Select a card for the detailed instructions.
- 01Plan your setupCheck your server, camera streams and network.View instructions
- 02Register your camerasCreate a company and add each camera’s serial number.View instructions
- 03Get and activate licencesRequest an invoice, pay by bank transfer, then activate your approved cameras.View instructions
- 04Deploy and testStart your edge server, connect cameras and check detection.View instructions
- 05Keep it runningMaintain your server and protect its licence files.View instructions
Step 3 includes invoice and payment and licence activation. Step 4 includes server startup and camera connection and testing. The administrator confirms settled payment before approving licences. Need help?
1. Prepare your deployment
Run the detector on an edge server, industrial PC or other approved computer that can reach your cameras. A camera supplies the video stream; registering it does not install software on the camera. Running detection inside a smart camera requires a separate compatibility assessment.
- Use Docker Engine on a dedicated Linux server with a stable, unique DMI hardware UUID. Docker Desktop and WSL are not supported for the customer image.
- Ask us to validate the server CPU, memory, camera count, stream resolution and required processing rate. There is no published minimum hardware specification or guaranteed throughput yet.
- The supplied customer image uses the CPU. GPU and NVIDIA Jetson deployments need a separately validated package.
- Obtain the camera manufacturer's RTSP stream address and an account permitted to read it. Keep these credentials on your local network.
- Allow HTTPS access to the portal for commercial activation or evaluation activation and refresh. The detector itself can operate without a cloud database in licensed edge mode.
Prepare your camera list, desired server, network diagram and sample footage. Validate detection at your site before relying on its output. The detector is not a certified safety system or a replacement for warehouse safety controls.
2. Register your companies and cameras
- Create an account, or sign in to My workspace.
- Under Your companies, add the company that owns the cameras.
- Under Register your cameras, choose the company and enter the camera name, manufacturer, model, serial number and optional location.
- Check each camera identity before submitting. Registered identities are fixed to their company. If you enter an incorrect identity, contact support for assistance.
A manufacturer and serial number combination cannot be registered twice within your account. Registration records your inventory; it does not verify ownership of the physical camera or grant a licence. Do not put camera passwords or RTSP URLs into the registration form.
3a. Request an invoice for your cameras
- In Request an invoice, choose the company and select its registered cameras.
- Enter the billing legal name, billing address and country. Add your tax identifier, purchase order reference and deployment notes if applicable.
- Acknowledge the non-transferable licence terms and submit the request.
- Keep the request reference. Its status and administrator replies appear under Your invoice requests. We also email confirmations and replies when email delivery succeeds.
The estimated licence subtotal is USD 299 per camera at the published early price. Taxes, final availability and invoice details require review. An invoice request is not a purchase confirmation. When an invoice is issued, it appears under Your invoices and perpetual licences. Open it to view the payment instructions and use your browser's Print function to save a PDF. Pay only an issued invoice, using its reference. The administrator records the full settled USD payment before activating the paid licences.
A camera can appear in only one open request. You may cancel a request awaiting review. For a request already under review, contact support; an administrator can decline it and release its cameras for a new request.
The published commercial offer
The proposed licence is a one-time USD 299 per registered camera channel at the early price, with a standard price of USD 399. It covers one active stream, perpetual use of the licensed software version, and two years of updates and support. Future upgrades are optional paid updates. The licence is non-transferable; replacing the camera requires a separate licence. Commercial invoices require configured seller details, enabled manual sales and licence signing. Payment is checked manually before the administrator activates the camera entitlements.
Commercial tokens have no expiry and are bound to the company, registered camera identities, edge-server public key, host hardware fingerprint and approved stream endpoints. Endpoint binding does not authenticate physical camera serial numbers, and host administrators can still bypass software binding by modifying the image or spoofing hardware identifiers. Non-transferability remains a contractual requirement as well as a restriction in the portal. Evaluation tokens remain time-limited.
3b. Activate paid perpetual camera licences
Use a dedicated Linux server with a stable, unique hardware UUID. Docker Desktop and WSL are not supported for this customer image. Keep the read-only host hardware mount in every command. Activation binds the signed licence to this server; copying the licence folder to a server with a different UUID will fail verification. Runtime settings cannot disable the customer image licence policy or replace its embedded trusted key. The binding does not protect against a host administrator modifying the image or spoofing hardware identifiers.
- Wait until the administrator has issued your invoice, confirmed the payment settlement and activated the licences. Your cameras will show Ready for edge activation.
- Obtain the customer image archive and trusted public signing key from the operator. Load it with
docker load -i aicraft-edge-customer.tarand name it locally withdocker tag aicraft-edge:customer aicraft-edge. The supplied customer image is required for licence enforcement. - Create a new local
licencefolder for the commercial server identity and arecordingsfolder. Do not reuse an identity registered to a sandbox device. - Prepare a private local
camera-map.jsonfile mapping each selected registered camera ID to its RTSP URL. Choose stable camera addresses or DNS names: company, camera, server identity and stream endpoint bindings cannot be reassigned through the portal. Credentials in the URL are excluded from the endpoint fingerprint; query parameters, host, port and stream path remain pinned. - In your workspace, enter the edge-server name, select the paid cameras and choose Create commercial activation code. Use the code within 15 minutes.
Example map, replacing the ID and stream with your registered camera:
{
"REGISTERED_CAMERA_ID": "rtsp://CAMERA_USER:CAMERA_PASSWORD@192.168.1.20:554/STREAM_PATH"
}Activate the server from PowerShell. Only endpoint hashes are sent to the portal; the camera-map file and credentials stay local.
New-Item -ItemType Directory -Force -Path .\licence, .\recordings
$env:EDGE_LICENSE_PUBLIC_KEY = 'PASTE_OPERATOR_SUPPLIED_PUBLIC_KEY'
docker run --mount type=bind,src=/sys/class/dmi/id,dst=/host-dmi,readonly --rm -it -v "${PWD}/licence:/licence" -v "${PWD}/camera-map.json:/camera-map.json:ro" aicraft-edge python scripts/edge_license.py activate-commercial --portal https://aicraftware.com --directory /licence --trusted-key "$env:EDGE_LICENSE_PUBLIC_KEY" --camera-map /camera-map.json
docker run --mount type=bind,src=/sys/class/dmi/id,dst=/host-dmi,readonly --rm -v "${PWD}/licence:/licence" aicraft-edge python scripts/edge_license.py verify --directory /licence --trusted-key "$env:EDGE_LICENSE_PUBLIC_KEY"Paste the commercial code at the concealed prompt. Verification should show environment: production, licence_type: perpetual_camera and expires_at: null. The perpetual entitlement has no expiry, but runtime startup requires Internet access and the service renews an exclusive runtime lease every minute. Offline grace lasts up to ten minutes from the last successful renewal. Keep the private device key protected on this server. Tokens without a signed hardware binding require operator reissuance for this image.
Run the container using the server startup settings, but omit EDGE_ALLOW_SANDBOX=true. For each source in the camera connection instructions, use its registered camera ID as source_id and the exact mapped stream endpoint. Commercial camera licences allow inference through the licensed source API; arbitrary uploaded image or video inference is not included in this entitlement.
To add newly purchased cameras to the same server, create another commercial code for the newly approved cameras and run the command with that server's existing licence folder and a map of only those new cameras. The tool returns a combined token while preserving the original bindings. Restart the runtime after updating its licence.
Updates and support run for two years from administrator licence activation. Expiry of that support period does not expire the perpetual token. The current runtime does not technically enforce software-version upgrade eligibility. The perpetual entitlement cannot be remotely erased or reclaimed by deactivation. Running the service requires a separate short-lived runtime lease. Hardware failure, refunds and identity recovery require operator assistance and do not automatically permit a transfer.
Alternative: Activate an evaluation licence
Use these steps only after an administrator has enabled sandbox licensing and supplied the runtime package and trusted public signing key. If the activation button is unavailable, use Get help; an invoice request alone cannot enable it.
- Load the supplied customer image and open PowerShell 7 in your deployment directory on the Linux server.
- Load the customer runtime image and create a persistent folder for this server's identity and licence.
- In your workspace, select Create device activation code for a company with available sandbox channels. Name the edge server and specify its channel count. The one-time code expires after 15 minutes.
- Run the activation command below. Paste the code at the concealed prompt.
docker load -i aicraft-edge-customer.tar
docker tag aicraft-edge:customer aicraft-edge
New-Item -ItemType Directory -Force -Path .\licence, .\recordings
$env:EDGE_LICENSE_PUBLIC_KEY = 'PASTE_OPERATOR_SUPPLIED_PUBLIC_KEY'
docker run --mount type=bind,src=/sys/class/dmi/id,dst=/host-dmi,readonly --rm -it -v "${PWD}/licence:/licence" aicraft-edge python scripts/edge_license.py activate --portal https://aicraftware.com --directory /licence --trusted-key "$env:EDGE_LICENSE_PUBLIC_KEY" --allow-sandbox
The tool creates device.key and saves licence.txt in your local licence folder. Keep the private key with this server and protect the folder with operating-system access controls. Do not copy the identity to another server or commit it to source control. Obtain the signing public key through the operator's agreed trusted channel; do not take it from an untrusted licence file.
Activation uses public-key proof and a one-time code. The trusted signing key is public information. The activation code, device private key and local API key must remain private.
4a. Start the licensed edge runtime
Create the shared host lock directory once with sudo install -d -m 0700 /var/lib/aicraft-edge/runtime-lock. Every customer container on this Linux server must mount this same directory. The local lock permits one process using the shared directory. The portal additionally grants one exclusive runtime lease per device entitlement, independently of folders or ports. Online startup is mandatory; renewal occurs every minute, with up to ten minutes of outage grace. A missing mount or an active owner prevents startup. Stop the running container before starting a replacement. A crash releases the local lock, but the portal reservation remains until its signed lease expires, so a replacement may need to wait up to ten minutes. Keep the lock file in place. A different local lock directory does not bypass the central lease check. A host administrator who modifies runtime code can still circumvent software enforcement.
Generate a strong local API key and run the container with its signed licence folder mounted read-only. The example binds the API to this server's loopback interface and keeps recorded clips outside the container.
$env:EDGE_API_KEY = docker run --mount type=bind,src=/sys/class/dmi/id,dst=/host-dmi,readonly --rm aicraft-edge python -c "import secrets; print(secrets.token_urlsafe(32))"
docker run --mount type=bind,src=/var/lib/aicraft-edge/runtime-lock,dst=/host-runtime-lock --mount type=bind,src=/sys/class/dmi/id,dst=/host-dmi,readonly -d --name aicraft-edge --restart unless-stopped --read-only --tmpfs /tmp:rw,noexec,nosuid,size=512m --cap-drop=ALL --security-opt=no-new-privileges=true -p 127.0.0.1:8000:8000 -v "${PWD}/licence:/licence:ro" -v "${PWD}/recordings:/recordings" -e EDGE_LICENSE_REQUIRED=true -e EDGE_LICENSE_DIRECTORY=/licence -e EDGE_LICENSE_PUBLIC_KEY -e EDGE_ALLOW_SANDBOX=true -e EDGE_API_KEY -e RECORDINGS_DIR=/recordings aicraft-edge
Invoke-RestMethod http://localhost:8000/health
Save the API key securely for your local integration. Send it in the X-API-Key header. A website login, online trial key or activation code cannot replace this local API key. Edge mode does not require the customer's Neon connection string or the website's email/payment secrets.
EDGE_ALLOW_SANDBOX=true permits the supplied evaluation licence. It does not make it a commercial licence. For paid perpetual licences, follow the commercial activation instructions and omit this sandbox setting.
For access from other computers, arrange a firewall-protected local service and TLS configuration with your IT team. Do not expose port 8000 or camera credentials directly to the public Internet. A successful health response confirms the service is reachable; use the next authenticated test to check licence enforcement and camera processing.
4b. Connect and test a camera
The container must be able to reach the camera's network address. Use its local IP or resolvable host name. localhost inside the container refers to the container itself. On Docker Desktop, a test stream running on the host can usually be addressed through host.docker.internal.
$headers = @{ 'X-API-Key' = $env:EDGE_API_KEY }
$camera = @{
source_id = 'loading_bay_01'
source = 'rtsp://CAMERA_USER:CAMERA_PASSWORD@192.168.1.20:554/STREAM_PATH'
source_type = 'rtsp'
every_n_frames = 5
reconnect = $true
}
Invoke-RestMethod -Method Post -Uri http://localhost:8000/source/start -Headers $headers -ContentType 'application/json' -Body ($camera | ConvertTo-Json)
Invoke-RestMethod -Uri http://localhost:8000/source/status/loading_bay_01 -Headers $headers
Invoke-RestMethod -Uri http://localhost:8000/source/events/loading_bay_01 -Headers $headers
Replace the example credentials and stream path with the camera manufacturer's values. Avoid sharing request bodies or terminal history containing camera passwords. For evaluation licences, the source ID is a local stream label. For commercial licences, use the registered camera ID and its bound stream endpoint from your camera map.
every_n_frames = 5 processes every fifth frame; it does not guarantee a specific frame rate. Review stream status and events, then check results against sample footage from your warehouse. Detection events may be empty when no forklift is detected.
Annotated previews and recordings are available through the local API. Use an authenticated client; opening a preview URL in a normal browser does not automatically send the API key. Consult the online API reference for route shapes, and http://localhost:8000/docs on your installed server for its own API reference.
Stop a stream
Invoke-RestMethod -Method Post -Uri http://localhost:8000/source/stop -Headers $headers -ContentType 'application/json' -Body (@{source_id='loading_bay_01'} | ConvertTo-Json)Repeat the connection process using a unique source ID for each approved camera. The evaluation licence limits simultaneous active sources to its channel allowance. Stopping a source releases an active-stream slot; it does not change the registered camera or transfer a commercial licence.
5. Maintain your deployment
The supplied customer image verifies its protected files at startup and while running. Keep the read-only startup settings and do not edit application or model files. A detected change disables inference and licence renewal; health reports an unavailable service. Restore operation by replacing the container with a clean operator-signed image. Restoring a file within the running container does not reset the disabled state. The licence reservation may remain active for up to ten minutes. Contact support if verification fails again.
Perpetual commercial entitlements do not expire. Runtime authorisation requires online startup and automatic renewal every minute, with up to ten minutes of grace after the last successful renewal. Inference stops when grace expires; restart online to obtain a new lease. Explicit licence or ownership denials stop processing upon receipt. This requirement applies after every restart; a cached entitlement alone cannot start the customer service. Protect the server identity and licence files, maintain the host and monitor camera connectivity. Updates and support are included for two years from activation; continued use of your licensed version remains permitted afterwards.
Evaluation licence refresh
An evaluation token expires at the earlier of 30 days after issuance or the sandbox entitlement's expiry. The customer service also requires a valid runtime lease and can operate through an outage only for its remaining lease grace period. Keeping it current requires an active entitlement and an HTTPS connection to the portal; there is no automatic entitlement-token refresh scheduler.
docker run --mount type=bind,src=/sys/class/dmi/id,dst=/host-dmi,readonly --rm -v "${PWD}/licence:/licence" aicraft-edge python scripts/edge_license.py verify --directory /licence --trusted-key "$env:EDGE_LICENSE_PUBLIC_KEY" --allow-sandbox
docker run --mount type=bind,src=/sys/class/dmi/id,dst=/host-dmi,readonly --rm -v "${PWD}/licence:/licence" aicraft-edge python scripts/edge_license.py refresh --portal https://aicraftware.com --directory /licence --trusted-key "$env:EDGE_LICENSE_PUBLIC_KEY" --allow-sandbox
docker restart aicraft-edge
The verification command prints the signed device ID, channel count and expiry. Confirm the computer clock is correct. Refresh writes a newly verified licence; restart the runtime after refreshing so it reliably reopens the updated mounted folder.
For an edge server without Internet access, the tool's request action can create a signed activation request for transfer to a connected workstation. An administrator must coordinate submission and return of the issued licence within the activation-code window. Only the activation request and issued licence need to travel; the private device key remains on the edge server. This request transfer does not provide air-gapped operation: online runtime lease acquisition and renewal are still required.
Deactivating an evaluation device blocks refresh but does not erase its issued offline token. Its channels stay reserved until that token expires. If a device identity is lost or hardware fails, contact support. Do not assume reinstalling or replacing hardware transfers a licence.
Keep recordings according to your company's retention policy. Edge recordings are stored in the local recordings folder; the hosted trial's 24-hour cleanup policy does not clean files on your server.
Performance and accuracy modes
The API defaults to inference_mode: performance: one forklift-model pass with the machinery appearance filter. Parked forklifts remain eligible. Difficult or distant forklifts may require the recovery checks available in accuracy mode.
For a camera, add "inference_mode": "accuracy" to the /source/start JSON request. For image or video uploads, send the multipart field inference_mode=accuracy. Accuracy mode enables additional high-resolution and control-model checks and will slow the processing framerate. Use performance or omit the field to prioritise speed. Restart a source to change its mode.
Real-time throughput and a maximum of 0.5 seconds per frame are not guaranteed on shared hosting. Benchmark the target hardware and workload. Video playback framerate and frame sampling are separate from detector processing speed.
Troubleshooting and support
| Problem | What to check |
|---|---|
| No activation button | The company needs sandbox channels and configured licence signing. Ask the administrator to arrange an evaluation. |
| Activation code expired or already used | Create a fresh code, use it within 15 minutes and run activation once for this server. |
| Missing or invalid edge API key / HTTP 401 | Send the local EDGE_API_KEY in X-API-Key. Check it matches the container environment. |
| Licence expired, wrong device or HTTP 403 | Verify the signed licence, pinned public key, device identity, mounted folder and clock. Refresh through the portal when entitled. |
| All licensed camera channels are in use / HTTP 409 | Stop unneeded sources or ask for additional evaluation channels. Registration and invoice requests do not increase the allowance. |
| Camera remains connecting or reconnecting | Check its power, network route, RTSP path, credentials and firewall. Test the stream from the server with a suitable video client. |
| Slow detection | Check CPU utilisation and stream resolution, reduce the number of streams, or increase every_n_frames. Ask us to validate the deployment. |
| No invoice email | Check spam and your workspace's request history. The request remains saved if email delivery fails. |
Inspect local container logs with docker logs --tail 100 aicraft-edge. Logs and error messages may contain stream addresses; remove passwords before sharing them.
Include the request reference, registered camera reference, runtime version or supplied package identifier, operating system, hardware details and a sanitised error message. Keep private keys, API keys, camera passwords and confidential footage out of the query. Administrator replies are emailed and retained in your workspace.
