A crew that only runs on your laptop can't serve users; deployment turns it into an API.
CrewAI AMP is CrewAI's hosted platform (at app.crewai.com) for running, monitoring and managing crews and flows. Plans and limits change, so check the website for current details.
Deployment from the CLI, run in the project folder:
crewai login # connect the CLI to your AMP account
crewai deploy create # register the project, upload local env vars
crewai deploy push # build and start the deployment
crewai deploy status # check progress or errors
crewai deploy logs # stream logsThe project must be a proper CrewAI project (JSON-first or classic) committed to a Git repository the platform can read. crewai deploy validate checks it first.
A deployed crew or flow gets an HTTP API, protected by a bearer token (a secret string sent in the Authorization header):
GET /inputslists the inputs the crew expects.POST /kickoffstarts a run with{"inputs": {...}}and returns akickoff_id.GET /status/{kickoff_id}returnsrunningwith progress, thencompletedwith theresult, orerror.POST /resumecontinues a run paused for human feedback.
Runs are asynchronous: you start one, then check its status every few seconds (polling) rather than holding one long request open.
Self-hosting is also possible: CrewAI is a normal Python library, so you can wrap kickoff in your own web service (for example with FastAPI) and use a task queue (a background job system that runs work outside the web request) for long runs. You then handle scaling, secrets, retries and tracing yourself.
Before deploying, set max_rpm, max_iter and timeouts so a misbehaving run can't burn through your API budget.
Example
# Call a deployed crew (URL and token come from the AMP dashboard)
import os, time, requests
BASE = os.environ["CREW_URL"] # e.g. https://<your-crew>.crewai.com
HEADERS = {"Authorization": f"Bearer {os.environ['CREW_TOKEN']}"}
print(requests.get(f"{BASE}/inputs", headers=HEADERS).json()) # {'inputs': ['topic']}
run = requests.post(f"{BASE}/kickoff", headers=HEADERS,
json={"inputs": {"topic": "AI in logistics"}}).json()
kickoff_id = run["kickoff_id"]
while True:
status = requests.get(f"{BASE}/status/{kickoff_id}", headers=HEADERS).json()
if status["status"] != "running": # "completed" or "error"
break
time.sleep(5)
print(status.get("result", status.get("error")))Remember
crewai login,deploy create,deploy push,deploy status/logs- Deployed crews expose
/inputs,/kickoff,/status/{id},/resume - Runs are async: start, then poll status; or self-host the library
Watch out for
- Holding an HTTP request open for a crew that runs for minutes instead of using kickoff plus status polling.