Owlhost agent deployment contract Start with the supplied https://owlshare.io invitation URL and follow its redemption contract. Owlshare returns a signed, service-bound enrollment ticket. POST that ticket to https://host.owlbox.ai/owlshare/enroll and privately retain the Owlhost bearer credential returned once. Read https://host.owlbox.ai/v1/providers before choosing a source format. The tenant owner controls the hosting account and credential; invited agents receive only bounded Owlhost permissions. For the available inline-source path, POST https://host.owlbox.ai/v1/apps with Authorization: Bearer CREDENTIAL and JSON {"name":"label","files":{"Dockerfile":"...","...":"..."}}. Maximum 50 files and 384 KiB. Listen on 0.0.0.0:8080 and include GET /health returning 200. Poll status_url until ready or failed; if feedback is present, follow actor_needed and action rather than repeatedly retrying. Never ask the human for a provider token; Owlhost keeps it server-side. Problem reporting is part of the contract. If enrollment, provider connection, deployment, health verification, documentation, or a missing capability blocks progress, file one sanitized ticket at POST https://host.owlbox.ai/v1/tickets and return its ticket id. Include provider, stage, safe error code or symptom, attempted outcome, and next step if known. Never include credentials, bearer tokens, private source, or unfiltered provider output. Do not silently stall or loop retries. After the first setup attempt for a provider, file one sanitized setup report even when successful. Include provider, outcome, successful path, failed attempts before success, unexpected human questions, documentation gaps, API gaps, and suggested improvements. Omit credentials, token fragments, private source, resource addresses, and raw provider output. Tenant agents use POST https://host.owlbox.ai/v1/tickets; Owlhost operators use POST https://host.owlbox.ai/admin/tickets. When a credential request returns waiting_for_human, retain its request id and poll the returned status_url at poll_after_seconds only while the human is actively completing the form. Resume when state is ready. Polling is the supported completion signal; do not claim a callback or unattended wake. Deployment requests may include deployment_shape and lifecycle. The default shape is portable_web_service. Legacy demo invitations retain temporary limits; owners and explicitly delegated host managers may request lifecycle=indefinite. Read each provider's deployment_shapes before submitting. Workload-specific products must use these generic shapes rather than requiring product-specific Owlhost adapters. Unsupported shapes are rejected before resource allocation and automatically ticketed. Indefinite infrastructure requires an owner or an explicitly delegated host-manager grant. For a reusable Hetzner host POST /v1/servers with name and one bare ssh-ed25519 public key. The response is allocated, not application-ready: verify SSH host identity and cloud-init. Retain the resource id; inspect /v1/apps/{id}; DELETE /v1/apps/{id} explicitly ends billing. Revoking agent access does not destroy its resources. Owners delegate this authority with POST /v1/host-manager-invitations. For a server created by the human, connect provider linux-docker through the SSH Vault form, then POST /v1/host/exec with command. Only owner or explicit manager grants can execute commands; credentials are never returned. Pin the server public host key from the trusted provider console. Resume from durable IDs instead of starting over: retain provider credential request IDs, application IDs/status_url values, and support ticket IDs. Ticket updates currently use polling only: GET https://host.owlbox.ai/v1/tickets no more frequently than every 30 seconds while actively waiting. Polling does not provide unattended wake delivery. Ask the human only for missing authority, secure vault entry, spending approval, or a material preference.