---
title: "Attach or replace the app repository and supplied deploy defaults"
method: POST
path: "/projects/{id}/app-repo"
---

# Attach or replace the app repository and supplied deploy defaults

`POST /projects/{id}/app-repo`

## Request

- Base URL: `https://api.eurobase.dev`
- URL: `https://api.eurobase.dev/projects/{id}/app-repo`
- Auth: none declared

## Path parameters

- `id` string, required

## Request body

- ProjectAppRepoRequest
  - `repoId` string, required
  - `repoFullName` string, required
  - `branch` string
  - `rootDir` string
  - `runCommand` string
  - `healthPath` string
  - `containerPort` integer

## Response `200`

Attached app repository

- ProjectAppRepoResponse
  - `project` ProjectSummary, required
    - `id` string, required
    - `name` string, nullable
    - `organizationId` string, nullable
    - `projectMembershipId` string, nullable
    - `projectRole` 'owner' | 'admin' | 'contributor' | 'null', nullable
    - `projectSlug` string, nullable
    - `projectHostname` string, nullable
    - `primaryHostname` string, nullable: Official address of the project: its active custom domain whose DNS points at Eurobase, the one that went live first when several do, otherwise projectHostname. projectHostname stays reserved and keeps serving.
    - `deploymentMode` 'runtime' | 'static', required
    - `lifecycleState` string, nullable
    - `deleteRequestedAt` string, date-time, nullable
    - `projectRoute` ProjectRoute, required
      - `status` 'healthy' | 'repairing' | 'degraded' | 'broken' | 'unknown', required
      - `reasonCode` 'none' | 'dns_record_missing' | 'dns_propagating' | 'domain_binding_missing' | 'tls_pending' | 'missing_project_upstream' | 'upstream_unreachable' | 'ingress_unreachable' | 'unmanaged_custom_domain' | 'scw_mutation_failed', required
      - `checkedAt` string, date-time, nullable
      - `lastRepairAt` string, date-time, nullable
      - `lastError` string, nullable
      - `managed` boolean, required
      - `convergenceState` 'recovering' | 'exhausted' | 'ready' | 'null', nullable
      - `upstream` ProjectUpstreamState, required
        - `status` 'healthy' | 'broken' | 'unknown', required
        - `reasonCode` 'none' | 'missing_project_upstream' | 'upstream_unreachable', required
        - `checkedAt` string, date-time, nullable
        - `lastError` string, nullable
    - `releaseUsability` ReleaseUsability, required
      - `status` 'reachable' | 'degraded' | 'blocked' | 'unknown', required
      - `reasonCode` 'none' | 'missing_live_release' | 'access_not_allowed' | 'route_repair_in_progress' | 'route_incident' | 'project_suspended', required
      - `lastLiveDeploymentId` string, nullable, required
    - `projectSummaryStatus` ProjectSummaryStatus
      - `label` string, required
      - `tone` 'neutral' | 'problem' | 'error', required
      - `code` 'setup_required' | 'route_issue' | 'deploy_failed' | 'deploy_unhealthy' | 'live_release_blocked' | 'status_check_delayed' | 'deploy_in_progress' | 'rollback_live' | 'healthy' | 'suspended', required
      - `detailTitle` string, nullable, required
      - `detail` string, nullable, required
    - `servingSuspension` ProjectServingSuspension: An operator suspension of the project's public serving (ADR 0080). Operator notes and evidence are never included.
      - `state` 'suspended', required
      - `reasonCategory` 'phishing' | 'malware' | 'shared_domain_abuse' | 'spam' | 'illegal_content' | 'legal_order' | 'other_policy_violation', required
      - `reasonLabel` string, required
      - `since` string, date-time, nullable, required
      - `supportEmail` string, required
      - `policyUrl` string, required
    - `sourceProfile` ProjectSourceProfileSummary, required
      - `framework` 'next' | 'astro' | 'svelte-kit' | 'nuxt' | 'react-router' | 'vite' | 'hono' | 'nestjs' | 'fastify' | 'express' | 'django' | 'fastapi' | 'flask' | 'laravel' | 'rails' | 'node' | 'python' | 'php' | 'ruby' | 'go' | 'java' | 'dotnet' | 'static', required
      - `frameworkLabel` string, required
      - `outputMode` 'runtime' | 'static', required
    - `sourceLock` ProjectSourceLock: ADR 0090: while locked, no caller can change the project repository, branch, root directory or deployment mode.
      - `locked` boolean, required
      - `lockedAt` string, date-time, nullable, required
  - `appRepo` AppRepo, required
    - `repoId` string, required
    - `repoName` string, nullable
    - `repoFullName` string, required
    - `branch` string, required
    - `rootDir` string, required
    - `runCommand` string, required
    - `healthPath` string, required
    - `containerPort` integer, required
    - `deploymentMode` 'runtime' | 'static', required
  - `appRuntimeTier` AppRuntimeTier
    - `code` 'euro-small' | 'euro-medium' | 'euro-large' | 'euro-xlarge', required
    - `label` string, required
    - `cpu` string
    - `memory` string
    - `limitsKnown` boolean
    - `cpuMillicores` integer, nullable
    - `memoryMb` integer, nullable
    - `minScale` integer, nullable, required
    - `maxScale` integer, nullable, required
    - `burnMultiplier` string, nullable
    - `workloadGuidance` string, nullable
    - `equivalentIncludedRuntimeHours` string, nullable
    - `selectable` boolean
    - `unavailableReason` string, nullable
    - `recoveryAction` string, nullable
    - `configurable` boolean, required
  - `appSourceProfile` AppSourceProfile
    - `sourceType` 'git_repo', required
    - `repository` object, nullable, required
      - `id` string, nullable
      - `name` string, nullable
      - `fullName` string, nullable
    - `branch` string, required
    - `rootDirectory` string, required
    - `rootCandidates` string[], required
    - `rootCandidateSetHash` string, nullable
    - `rootChoiceRequired` boolean, required
    - `rootChoiceConfirmed` boolean, required
    - `sourceBuildEngine` 'direct-static-v1' | 'paketo-v1' | 'workers-v1', required
    - `directStatic` boolean, required
    - `framework` 'next' | 'astro' | 'svelte-kit' | 'nuxt' | 'react-router' | 'vite' | 'hono' | 'nestjs' | 'fastify' | 'express' | 'django' | 'fastapi' | 'flask' | 'laravel' | 'rails' | 'node' | 'python' | 'php' | 'ruby' | 'go' | 'java' | 'dotnet' | 'static' | 'unknown', required
    - `frameworkLabel` string, required
    - `outputMode` 'runtime' | 'static', required
    - `appRuntimeTierId` 'euro-small' | 'euro-medium' | 'euro-large' | 'euro-xlarge' | 'null', nullable
    - `port` integer, nullable
    - `healthPath` string, nullable
    - `appRuntimeTier` AppRuntimeTier
      - `code` 'euro-small' | 'euro-medium' | 'euro-large' | 'euro-xlarge', required
      - `label` string, required
      - `cpu` string
      - `memory` string
      - `limitsKnown` boolean
      - `cpuMillicores` integer, nullable
      - `memoryMb` integer, nullable
      - `minScale` integer, nullable, required
      - `maxScale` integer, nullable, required
      - `burnMultiplier` string, nullable
      - `workloadGuidance` string, nullable
      - `equivalentIncludedRuntimeHours` string, nullable
      - `selectable` boolean
      - `unavailableReason` string, nullable
      - `recoveryAction` string, nullable
      - `configurable` boolean, required
    - `detection` AppSourceDetection, required
      - `status` 'not_requested' | 'pending' | 'detected' | 'needs_review' | 'failed' | 'unavailable', required
      - `reason` 'none' | 'no_match' | 'ambiguous' | 'cap_exceeded' | 'timeout' | 'rate_limited' | 'repo_access_unavailable' | 'detector_error', required
      - `confidence` 'high' | 'medium' | 'low' | 'unknown', required
      - `detectedAt` string, date-time, nullable
      - `commitSha` string, nullable
      - `treeSha` string, nullable
      - `detectorVersion` string, nullable, required
      - `evidence` AppSourceDetectionEvidence[], required
        - `path` string, required
        - `reason` string, required
      - `warnings` string[], required
    - `overrideState` 'auto' | 'custom_override' | 'detected_but_unconfirmed', required
    - `canDeploy` boolean, required
    - `blockedReason` string, nullable
    - `blockedMessage` string, nullable
    - `sourceRuntime` 'ruby' | 'dotnet' | 'go' | 'python' | 'php' | 'java' | 'node' | 'null', nullable
    - `serviceType` 'web_service' | 'static_site' | 'null', nullable
    - `packageManager` 'npm' | 'yarn' | 'null', nullable
    - `buildCommand` string, nullable
    - `startCommand` string, nullable
    - `publishDirectory` string, nullable
    - `sourceBuild` AppSourceBuildPlan
      - `runtime` string, nullable, required
      - `packageManager` string, nullable, required
      - `blockedReason` string, nullable, required
      - `procfileWeb` string, nullable, required
      - `scripts` string[], required
      - `startRequired` boolean, required
      - `buildAvailable` boolean, required
      - `startLooksLikeDevServer` boolean
      - `defaults` object, required
        - `serviceType` 'web_service' | 'static_site', required
        - `buildCommand` string, nullable, required
        - `startCommand` string, nullable, required
        - `publishDirectory` string, nullable, required
    - `buildHints` object, nullable
      - `runtime` string, nullable
      - `pythonVersion` string, nullable
      - `nodeVersion` string, nullable
      - `nodeLaunchpoint` string, nullable
  - `ok` boolean

## Other responses

- `400`: Invalid attach request, including a missing or unavailable repository, invalid deploy defaults, or deploymentMode (reason deployment-mode-not-settable)
- `409`: Repository access is missing, the requested app repository branch is already attached to another active project, or the project source is locked (reason project-source-locked)

---

[API](https://skmtc.dev/eurobase/apis/eurobase-api.md) · [All operations](https://skmtc.dev/eurobase/apis/eurobase-api/llms.txt) · [OpenAPI document](https://skmtc.dev/eurobase/apis/eurobase-api/revisions/5266a299d18a?raw)
