Deploying to CrewAI AMP

CrewAI · Expert · 12 min

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 logs

The 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 /inputs lists the inputs the crew expects.
  • POST /kickoff starts a run with {"inputs": {...}} and returns a kickoff_id.
  • GET /status/{kickoff_id} returns running with progress, then completed with the result, or error.
  • POST /resume continues 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.

Check yourself

  1. After POST /kickoff returns a kickoff_id, how do you get the result?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.crewai.com/en/api-reference/status