Skip to main content
POST
/
cost-estimations
Create cost estimation
curl --request POST \
  --url https://api.example.com/cost-estimations
A cost estimation resolves the repositories you plan to scan, detects applications within them, and returns a predicted credit cost. A completed cost estimation is required before calling POST /scans. Cost estimations run asynchronously. The POST returns a record in pending or running state; poll GET /cost-estimations/{id} until status reaches completed, partial, or failed.
Scope required: write

Request

curl -X POST https://api.hacktron.ai/v1/cost-estimations \
  -H "X-Api-Key: $HACKTRON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "nightly-estimate",
    "repos": [
      {
        "source": "connected",
        "repo_url": "https://github.com/acme/backend",
        "branch": "main"
      }
    ]
  }'

Body

FieldTypeRequiredDescription
namestringNoFriendly label for this estimation. Max 255 chars.
reposobject[]Yes1–20 repositories to estimate. Each entry is one of the repo shapes below, identified by source.

Repo shapes

Repositories use a discriminated union on the source field.

connected — a repository already synced to Hacktron via GitHub, GitLab, or Bitbucket

FieldTypeRequiredDescription
source"connected"YesDiscriminator.
repo_urlstringYesFull HTTPS URL of the repository. Max 500 chars.
branchstringYesBranch to estimate. Max 255 chars.
github_installation_idintNoSpecific GitHub App installation ID to use.

public — a public git repository Hacktron can clone anonymously

FieldTypeRequiredDescription
source"public"YesDiscriminator.
repo_urlstringYesFull HTTPS URL. Max 500 chars.
branchstringYesBranch to estimate. Max 255 chars.

upload — a previously uploaded archive

FieldTypeRequiredDescription
source"upload"YesDiscriminator.
archive_idUUIDYesID of a scan archive you uploaded.

Response

201 Created — the estimation is queued. Poll GET /cost-estimations/{id} until status reaches a terminal value.
{
  "id": "b4f5c6a1-2d3e-4f56-9a8b-0c1d2e3f4a5b",
  "organization_id": "f336d0bc-b841-465b-8045-024475c079dd",
  "user_id": "e5a6d7c8-9b0a-1c2d-3e4f-5a6b7c8d9e0f",
  "name": "nightly-estimate",
  "task_id": "cost_est_acme-backend_1712345678",
  "status": "pending",
  "repos": [
    {
      "source": "connected",
      "repo_url": "https://github.com/acme/backend",
      "branch": "main"
    }
  ],
  "total_credits": null,
  "repo_results": null,
  "error": null,
  "created_at": "2026-04-13T12:00:00.000Z",
  "updated_at": "2026-04-13T12:00:00.000Z"
}

Terminal statuses

StatusMeaning
completedAll repos were estimated successfully. total_credits is populated.
partialSome repos completed, others failed. Check repo_results[].status for details.
failedThe whole estimation failed. error contains a message.
Once in a terminal state, an estimation is immutable. Pass its id as cost_estimation_id to POST /scans to start the scan.

Errors

  • 400 — invalid or missing fields (for example, more than 20 repos, invalid source, or missing repo_url).
  • 401 / 403 — authentication or scope failure.