Skip to content

Conversation

ankur-arch
Copy link
Contributor

@ankur-arch ankur-arch commented Sep 16, 2025

Summary by CodeRabbit

  • Documentation
    • Added a comprehensive guide for end-to-end Vercel app deployment with Prisma Postgres, including a complete programmatic, copy-pasteable TypeScript workflow.
    • Guide covers prerequisites, error handling and retry strategies, security, production considerations, monitoring, next steps, and a live-demo reference.
    • Updated site navigation to surface the new guide under Guides → Integration Solutions for easier discovery.

@ankur-arch ankur-arch self-assigned this Sep 16, 2025
Copy link
Contributor

coderabbitai bot commented Sep 16, 2025

Walkthrough

Adds a new MDX guide demonstrating a programmatic Vercel + Prisma Postgres deployment workflow (CONFIG, six-step TypeScript API sequence, retry/error helpers, and deployApp orchestrator) and updates sidebars.ts to register the guide; sidebar edits also include non-functional trailing-comma formatting changes.

Changes

Cohort / File(s) Summary
New guide: Vercel app deployment
content/800-guides/380-vercel-app-deployment.mdx
Adds an end-to-end MDX guide with TypeScript examples covering a centralized CONFIG, six Vercel REST API calls (project, authorization, database, connection, deployment, transfer), an orchestrator deployApp() example, retry/error helpers, prerequisites, and references.
Sidebar registration & formatting
sidebars.ts
Registers guides/vercel-app-deployment under Guides → Integration Solutions and applies trailing-comma formatting adjustments across sidebar entries; no behavioral changes.

Sequence Diagram(s)

sequenceDiagram
  participant Dev as Developer script
  participant VercelAPI as Vercel REST API
  participant PrismaStore as Prisma Postgres (store)
  participant VercelProject as Vercel Project / Deployment
  rect rgba(0,128,96,0.08)
    note right of Dev: deployApp() orchestrator (high-level)
  end
  Dev->>VercelAPI: POST /v10/projects (createProject)
  VercelAPI-->>Dev: projectId
  Dev->>VercelAPI: POST /v1/integrations/billing/authorization (createPrismaAuthorization)
  VercelAPI-->>Dev: authorizationId
  Dev->>VercelAPI: POST /v1/storage/stores/integration (createPrismaDatabase)
  VercelAPI-->>PrismaStore: provision DB
  VercelAPI-->>Dev: storeId, connectionString
  Dev->>VercelAPI: POST /v1/integrations/installations/{configId}/products/{PRISMA_PRODUCT_ID}/resources/{storeId}/connections (connectDatabaseToProject)
  VercelAPI-->>Dev: connection confirmation
  Dev->>VercelAPI: POST /v13/deployments (deployApplication)
  VercelAPI-->>VercelProject: build & deploy
  VercelAPI-->>Dev: deploymentUrl
  Dev->>VercelAPI: POST /v9/projects/{projectId}/transfer-request (createProjectTransfer)
  VercelAPI-->>Dev: transferCode / claimUrl
  note right of Dev: deployApp() returns consolidated result (projectId, url, transfer info)
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • feat: add bun guide #7092 — Adds a new guide MDX and updates sidebars; similar pattern of adding documentation and registering it in the site sidebar.

Suggested reviewers

  • nurul3101
  • petradonka
  • nikolasburk

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "feat: add vercel deployment guide" is a short, single-sentence summary that accurately reflects the main change in the changeset (adding a Vercel deployment guide and updating the sidebar). It is concise, clear, and developer-facing, making the primary intent easy to understand for teammates scanning PR history.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch DC-5025-vercel-guide

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 333a6d4 and d8b557c.

📒 Files selected for processing (1)
  • content/800-guides/380-vercel-app-deployment.mdx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • content/800-guides/380-vercel-app-deployment.mdx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Check internal links
  • GitHub Check: runner / linkspector
  • GitHub Check: Lost Pixel

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

Dangerous URL check

No absolute URLs to prisma.io/docs found.
No local URLs found.

Copy link
Contributor

Copy link
Contributor

Redirect check

This PR probably requires the following redirects to be added to static/_redirects:

  • This PR does not change any pages in a way that would require a redirect.

Copy link
Contributor

Images automagically compressed by Calibre's image-actions

Compression reduced images by 87.7%, saving 274.7 KB.

Filename Before After Improvement Visual comparison
static/img/guides/vercel_app_deployments.png 313.2 KB 38.6 KB 87.7% View diff

Copy link

cloudflare-workers-and-pages bot commented Sep 16, 2025

Deploying docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: 5649dc5
Status: ✅  Deploy successful!
Preview URL: https://0fa3e06d.docs-51g.pages.dev
Branch Preview URL: https://dc-5025-vercel-guide.docs-51g.pages.dev

View logs

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (7)
content/800-guides/380-vercel-app-deployment.mdx (6)

137-158: Use the shared error/ retry helpers in all API calls.

createProject (and later functions) don’t use handleApiErrors/apiCallWithRetry, so failures will be silent and inconsistent with the guide’s best practices.

-  const response = await fetch(
+  const response = await apiCallWithRetry(
     `${CONFIG.VERCEL_API_URL}/v10/projects?teamId=${CONFIG.TEAM_ID}`,
     {
       method: "POST",
       headers: {
         Authorization: `Bearer ${CONFIG.ACCESS_TOKEN}`,
         "Content-Type": "application/json",
       },
       body: JSON.stringify({ name: projectName }),
     }
   );
-  const project = await response.json();
+  await handleApiErrors(response, "Create project");
+  const project = await response.json();

369-405: fileSha is undefined; make it a parameter and wire in error/retry.

The orchestration example won’t run as-is. Accept fileSha (or upload first) and consistently use your helpers.

-async function deployApp() {
+async function deployApp(fileSha: string) {
   console.log("🚀 Starting instant deployment...");
@@
-  const deployment = await deployApplication(project.name, fileSha);
+  const deployment = await deployApplication(project.name, fileSha);
@@
   return {
     projectId: project.id,
     deploymentUrl: `https://${deployment.url}`,
     claimCode: transfer.code,
     claimUrl: transfer.claimUrl,
   };
 }

447-466: Surface parsed JSON where possible and include response snippet in errors.

Parsing only text() loses structure. Prefer JSON where applicable and include truncated payload for diagnostics.

-    const errorData = await response.text();
+    const raw = await response.text();
+    let errorData: unknown = raw;
+    try { errorData = JSON.parse(raw); } catch {}
@@
-        throw new Error(`${operation} failed: ${response.status} - ${errorData}`);
+        throw new Error(`${operation} failed: ${response.status} - ${typeof errorData === "string" ? errorData.slice(0, 500) : JSON.stringify(errorData).slice(0, 500)}`);

475-492: Respect Retry-After, add jitter, and support timeouts.

This improves resilience under rate limits and network stalls.

-async function apiCallWithRetry(url: string, options: RequestInit, maxRetries = 3) {
+async function apiCallWithRetry(url: string, options: RequestInit, maxRetries = 3, timeoutMs = 15000) {
   for (let attempt = 1; attempt <= maxRetries; attempt++) {
     try {
-      const response = await fetch(url, options);
+      const ac = new AbortController();
+      const t = setTimeout(() => ac.abort(), timeoutMs);
+      const response = await fetch(url, { ...options, signal: ac.signal });
+      clearTimeout(t);
       
       if (response.status === 429) {
-        const waitTime = Math.pow(2, attempt) * 1000; // Exponential backoff
-        await new Promise(resolve => setTimeout(resolve, waitTime));
+        const ra = response.headers.get("retry-after");
+        const base = ra ? Number(ra) * 1000 : Math.pow(2, attempt) * 1000;
+        const jitter = Math.floor(Math.random() * 250);
+        await new Promise(resolve => setTimeout(resolve, base + jitter));
         continue;
       }
       
       return response;
     } catch (error) {
       if (attempt === maxRetries) throw error;
     }
   }
 }

499-506: Add an explicit note to avoid logging or storing secrets (tokens and database URLs).

Strengthen the guidance given the examples return sensitive values earlier.

 - **Store tokens securely**: Never expose API tokens in client-side code
+ - **Never log or store secrets**: Avoid printing ACCESS_TOKEN, connection strings (DATABASE_URL), or other credentials to logs or analytics

121-129: Avoid hard-coding product IDs — use Vercel's 'prisma' slug and VERCEL_TOKEN

  • Replace PRISMA_PRODUCT_ID = "iap_yVdbiKqs5fLkYDAB" with the Marketplace slug "prisma" (use integrationProductIdOrSlug = "prisma").
  • Rename ACCESS_TOKEN → VERCEL_TOKEN and store it as a Sensitive env var; optionally namespace other vars as VERCEL_TEAM_ID and VERCEL_INTEGRATION_CONFIG_ID.

File: content/800-guides/380-vercel-app-deployment.mdx lines 121-129.

sidebars.ts (1)

549-559: Prefer type: "doc" for internal pages over raw href for consistency and broken-link checks.

Using doc ids enables Docusaurus validation and versioning. Keep href only for external links.

Example:

-{
-  type: "link",
-  label: "Integrating the Vercel AI SDK in a Next.js application",
-  href: "/guides/ai-sdk-nextjs",
-},
+{
+  type: "doc",
+  id: "guides/ai-sdk-nextjs",
+  label: "Integrating the Vercel AI SDK in a Next.js application",
+},

Also applies to: 572-582, 595-600

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 04a0882 and 333a6d4.

⛔ Files ignored due to path filters (1)
  • static/img/guides/vercel_app_deployments.png is excluded by !**/*.png
📒 Files selected for processing (2)
  • content/800-guides/380-vercel-app-deployment.mdx (1 hunks)
  • sidebars.ts (4 hunks)
🔇 Additional comments (5)
sidebars.ts (2)

604-606: LGTM on formatting tweaks.

Trailing commas/comments here are harmless and match existing style.


453-454: Ensure sidebar entry id matches MDX doc id/slug

sidebars.ts references "guides/vercel-app-deployment" (sidebars.ts:453) but content/800-guides/380-vercel-app-deployment.mdx frontmatter has no id or slug. Add slug: /guides/vercel-app-deployment or id: guides/vercel-app-deployment to the MDX frontmatter, or update the sidebar entry to the doc's actual id.

content/800-guides/380-vercel-app-deployment.mdx (3)

33-33: Validate external links and follow redirects.

File: content/800-guides/380-vercel-app-deployment.mdx Lines: 33-33

[Try the demo](https://pris.ly/vercel_app_deployment_demo?utm_source=docs).

HEAD check results:

Action: follow the 302 redirects (e.g., curl -IL) and confirm the final URLs and any fragment anchors resolve to 200 and the intended content; update links/anchors or replace with final destination URLs if they will 404 at publish time.

Also applies to: 362-363, 407-407, 556-561


332-355: Add API error handling; TTL is 24h — don't rely on returnUrl for expired/invalid codes.

File: content/800-guides/380-vercel-app-deployment.mdx (lines 332-355)

  • Replace the raw fetch with apiCallWithRetry and call handleApiErrors on the response; handle non-2xx results (show a user-facing error/fallback) instead of assuming the claim flow will redirect.
  • Vercel docs: the POST returns a transfer code valid for 24 hours and the claim URL accepts returnUrl; behavior for invalid/expired codes is not documented (the accept endpoint surfaces 4xx/422 errors), so explicitly handle these error cases in code. (vercel.com)

170-200: metadata should be an object, not a JSON string.

Vercel's integrations/marketplace examples and responses use metadata as a JSON object; keep it as an object unless this exact endpoint explicitly requires a string. (vercel.com)

-        metadata: JSON.stringify({ region: "iad1" }),
+        metadata: { region: "iad1" },

Comment on lines +1 to +8
---
title: 'Instant app deployment with Vercel and Prisma Postgres'
metaTitle: 'Instant app deployment with Vercel and Prisma Postgres'
description: 'Learn how to programmatically deploy applications with Vercel and Prisma Postgres using the instant deployment API'
sidebar_label: 'Vercel app deployment'
image: '/img/guides/vercel_app_deployments.png'
community_section: true
---
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add a stable slug/id so the sidebar link resolves.

The sidebar references guides/vercel-app-deployment, but this file lacks a matching slug or id. Add a slug to avoid 404s and decouple from the numeric path.

 ---
 title: 'Instant app deployment with Vercel and Prisma Postgres'
 metaTitle: 'Instant app deployment with Vercel and Prisma Postgres'
 description: 'Learn how to programmatically deploy applications with Vercel and Prisma Postgres using the instant deployment API'
 sidebar_label: 'Vercel app deployment'
 image: '/img/guides/vercel_app_deployments.png'
 community_section: true
+slug: /guides/vercel-app-deployment
 ---
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
---
title: 'Instant app deployment with Vercel and Prisma Postgres'
metaTitle: 'Instant app deployment with Vercel and Prisma Postgres'
description: 'Learn how to programmatically deploy applications with Vercel and Prisma Postgres using the instant deployment API'
sidebar_label: 'Vercel app deployment'
image: '/img/guides/vercel_app_deployments.png'
community_section: true
---
---
title: 'Instant app deployment with Vercel and Prisma Postgres'
metaTitle: 'Instant app deployment with Vercel and Prisma Postgres'
description: 'Learn how to programmatically deploy applications with Vercel and Prisma Postgres using the instant deployment API'
sidebar_label: 'Vercel app deployment'
image: '/img/guides/vercel_app_deployments.png'
community_section: true
slug: /guides/vercel-app-deployment
---
🤖 Prompt for AI Agents
In content/800-guides/380-vercel-app-deployment.mdx around lines 1 to 8, the
file frontmatter is missing a stable slug/id so the sidebar link to
guides/vercel-app-deployment can 404; add a slug (and optionally an id) to the
YAML frontmatter such as slug: 'guides/vercel-app-deployment' (or id:
'guides/vercel-app-deployment') to decouple the URL from the numeric path and
ensure the sidebar link resolves.

Comment on lines +214 to +246
async function createPrismaDatabase(
projectName: string,
authId: string,
configId: string
): Promise<{ id: string; connectionString?: string }> {
const response = await fetch(
`${CONFIG.VERCEL_API_URL}/v1/storage/stores/integration?teamId=${CONFIG.TEAM_ID}`,
{
method: "POST",
headers: {
Authorization: `Bearer ${CONFIG.ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
metadata: { region: "iad1" },
billingPlanId: "pro",
name: `postgres-${projectName}`,
integrationConfigurationId: configId,
integrationProductIdOrSlug: CONFIG.PRISMA_PRODUCT_ID,
authorizationId: authId,
source: "marketplace",
}),
}
);

const storageData = await response.json();

return {
id: storageData.store.id,
connectionString: storageData.store.connectionString,
};
}
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Do not surface raw connection strings in return values/logs.

connectionString is sensitive. Avoid returning or logging it in examples; rely on the connection injected into env vars after linking.

-): Promise<{ id: string; connectionString?: string }> {
+): Promise<{ id: string }> {
   const response = await fetch(
     `${CONFIG.VERCEL_API_URL}/v1/storage/stores/integration?teamId=${CONFIG.TEAM_ID}`,
     {
       method: "POST",
       headers: {
         Authorization: `Bearer ${CONFIG.ACCESS_TOKEN}`,
         "Content-Type": "application/json",
       },
       body: JSON.stringify({
         metadata: { region: "iad1" },
         billingPlanId: "pro",
         name: `postgres-${projectName}`,
         integrationConfigurationId: configId,
-        integrationProductIdOrSlug: CONFIG.PRISMA_PRODUCT_ID,
+        integrationProductIdOrSlug: CONFIG.PRISMA_PRODUCT_ID,
         authorizationId: authId,
         source: "marketplace",
       }),
     }
   );
 
   const storageData = await response.json();
   
   return {
-    id: storageData.store.id,
-    connectionString: storageData.store.connectionString,
+    id: storageData.store.id,
   };
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async function createPrismaDatabase(
projectName: string,
authId: string,
configId: string
): Promise<{ id: string; connectionString?: string }> {
const response = await fetch(
`${CONFIG.VERCEL_API_URL}/v1/storage/stores/integration?teamId=${CONFIG.TEAM_ID}`,
{
method: "POST",
headers: {
Authorization: `Bearer ${CONFIG.ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
metadata: { region: "iad1" },
billingPlanId: "pro",
name: `postgres-${projectName}`,
integrationConfigurationId: configId,
integrationProductIdOrSlug: CONFIG.PRISMA_PRODUCT_ID,
authorizationId: authId,
source: "marketplace",
}),
}
);
const storageData = await response.json();
return {
id: storageData.store.id,
connectionString: storageData.store.connectionString,
};
}
```
async function createPrismaDatabase(
projectName: string,
authId: string,
configId: string
): Promise<{ id: string }> {
const response = await fetch(
`${CONFIG.VERCEL_API_URL}/v1/storage/stores/integration?teamId=${CONFIG.TEAM_ID}`,
{
method: "POST",
headers: {
Authorization: `Bearer ${CONFIG.ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
metadata: { region: "iad1" },
billingPlanId: "pro",
name: `postgres-${projectName}`,
integrationConfigurationId: configId,
integrationProductIdOrSlug: CONFIG.PRISMA_PRODUCT_ID,
authorizationId: authId,
source: "marketplace",
}),
}
);
const storageData = await response.json();
return {
id: storageData.store.id,
};
}
🤖 Prompt for AI Agents
In content/800-guides/380-vercel-app-deployment.mdx around lines 214 to 246, the
function currently returns storageData.store.connectionString which exposes a
sensitive DB connection string; remove the connectionString from the returned
object (return only the store id), do not log or surface the raw connection
string anywhere in examples, and rely on the connection being injected into env
vars after linking; optionally validate storageData.store exists and throw a
safe error message if missing but never include the connection string in return
values or logs.

Comment on lines +260 to +279
async function connectDatabaseToProject(
projectId: string,
storeId: string,
configId: string
): Promise<void> {
await fetch(
`${CONFIG.VERCEL_API_URL}/v1/integrations/installations/${configId}/products/${CONFIG.PRISMA_PRODUCT_ID}/resources/${storeId}/connections?teamId=${CONFIG.TEAM_ID}`,
{
method: "POST",
headers: {
Authorization: `Bearer ${CONFIG.ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ projectId }),
}
);

console.log("✅ Database connected to project");
}
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

🧩 Analysis chain

Verify the “connect resource to project” endpoint path and params.

The path uses installations/{configId}/products/{PRISMA_PRODUCT_ID}/resources/{storeId}/connections. Confirm the expected installations vs configurations, required IDs, and query/body fields.


🌐 Web query:

What is the correct Vercel endpoint to connect an Integration resource (Prisma Postgres store) to a Project, and which IDs are required (installation/configuration, product, resource, project)?

💡 Result:

Endpoint:

  • POST /v1/integrations/installations/{integrationConfigurationId}/resources/{resourceId}/connections. [1]

Required IDs/fields:

  • integrationConfigurationId — the installation / integration configuration ID (path). [1]
  • resourceId — the provider resource ID (path). [1][2]
  • projectId — the Vercel project ID (JSON body, required). [1]

Optional/query:

  • teamId or slug — to act on behalf of a team (query parameters). [1]

Notes:

  • productId is returned in the resource metadata but is not required to call this endpoint. [2]

Sources:
[1] Vercel REST API — Connect integration resource to project (POST).
[2] Vercel REST API — Get Integration Resource (resource fields).


Fix endpoint path — remove /products/{productId} and call Vercel’s connect-resource endpoint.

Use POST /v1/integrations/installations/{integrationConfigurationId}/resources/{resourceId}/connections. Path params: integrationConfigurationId (configId) and resourceId (storeId). Request body must include { projectId } (already present). Optional: ?teamId or ?slug. productId is not required and should be removed from the URL.

File: content/800-guides/380-vercel-app-deployment.mdx — lines 260–279.

🤖 Prompt for AI Agents
In content/800-guides/380-vercel-app-deployment.mdx around lines 260 to 279, the
request URL incorrectly includes /products/{productId}; change the endpoint to
POST
/v1/integrations/installations/{integrationConfigurationId}/resources/{resourceId}/connections
by removing the /products/{productId} segment and using configId as
integrationConfigurationId and storeId as resourceId in the path, keep the JSON
body { projectId } as-is and retain optional query params like ?teamId or ?slug
if needed.

Comment on lines +290 to +318
async function deployApplication(
projectName: string,
fileSha: string
): Promise<{ id: string; url: string }> {
const response = await fetch(
`${CONFIG.VERCEL_API_URL}/v13/deployments?teamId=${CONFIG.TEAM_ID}`,
{
method: "POST",
headers: {
Authorization: `Bearer ${CONFIG.ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
files: [{ file: ".vercel/source.tgz", sha: fileSha }],
name: `deployment-${Date.now()}`,
projectSettings: { framework: "nextjs" },
project: projectName,
}),
}
);

const deploymentData = await response.json();

return {
id: deploymentData.id,
url: deploymentData.alias?.[0] || deploymentData.url,
};
}
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

🧩 Analysis chain

Deployment flow misses file upload and ‘target’; verify project field semantics.

  • You reference fileSha without showing how to upload and compute it.
  • For production URLs, set target: "production".
  • Confirm whether project expects project ID or name in v13.
       body: JSON.stringify({
         files: [{ file: ".vercel/source.tgz", sha: fileSha }],
-        name: `deployment-${Date.now()}`,
+        name: `deployment-${Date.now()}`,
         projectSettings: { framework: "nextjs" },
-        project: projectName,
+        project: projectName, // use projectId if required
+        target: "production",
       }),

🌐 Web query:

For POST /v13/deployments: 
1) How to upload files and compute `sha` for `.vercel/source.tgz`? 
2) Is `project` a project ID or name? 
3) Is `target: "production"` required for production URLs?

💡 Result:

Short answers:

  1. Upload + compute sha:
  • Compute a SHA1 of the file contents (the API expects the file SHA1). On Unix you can use shasum, e.g. shasum -a 1 (Vercel guide shows using shasum and then sending that value as the x-vercel-digest header). Then POST the raw file to the upload endpoint with header x-vercel-digest (and proper Content-Length). See Vercel guide and the Upload Deployment Files docs. [1][2]
  1. project field:
  • Vercel accepts either a project ID or project name for the project endpoints (there are endpoints like GET /v9/projects/{idOrName} that accept id OR name). Use the project ID when you need an unambiguous identifier. [3]
  1. target: "production":
  • target is optional. If omitted the deployment is a preview deployment; to assign production aliases / mark it as a production deployment you should set target: "production". So include target: "production" when you want production URLs / alias promotion. [4][2]

Sources:
[1] Vercel guide — “How do I generate an SHA for uploading a file to the Vercel API?”.
[2] Vercel REST API — Upload Deployment Files (POST /v2/files) (x-vercel-digest / Content-Length).
[3] Vercel REST API — Find a project by id or name (GET /v9/projects/{idOrName}).
[4] Vercel POST /v13/deployments docs / integration reference (target: optional — use "production" to assign aliases).


Implement file upload (SHA1) + set target="production"; prefer project ID

  • Compute SHA1 for .vercel/source.tgz (e.g., shasum -a 1 .vercel/source.tgz) and upload the raw file to Vercel's upload endpoint (POST /v2/files) with header x-vercel-digest: and correct Content-Length; use that SHA as files[].sha in the v13 deployment request.
  • Add target: "production" to get production aliases / mark the deployment as production.
  • Use project ID (preferred) rather than name for unambiguous behavior — v13 accepts either, but ID is safer.

Location: content/800-guides/380-vercel-app-deployment.mdx — deployApplication (lines 290-318).

       body: JSON.stringify({
         files: [{ file: ".vercel/source.tgz", sha: fileSha }],
-        name: `deployment-${Date.now()}`,
+        name: `deployment-${Date.now()}`,
         projectSettings: { framework: "nextjs" },
-        project: projectName,
+        project: projectName, // use projectId if required
+        target: "production",
       }),

- `POST /v13/deployments` - Deploy application code
- `POST /v9/projects/{id}/transfer-request` - Generate claim code for user transfer

## Required API keys and environment variables
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ankur-arch do you need a Prisma token also?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants