@lovable.dev/sdk
v0.1.10
Published
TypeScript SDK for the Lovable API
Readme
@lovable.dev/sdk
TypeScript SDK for the Lovable API.
Currently in preview.
Installation
npm install @lovable.dev/sdkUsage
import { LovableClient } from "@lovable.dev/sdk";
const client = new LovableClient({
apiKey: "lov_your-api-key",
});
// List workspaces
const workspaces = await client.listWorkspaces();
// 1. Create a project
const project = await client.createProject(workspaces[0].id, {
description: "Best todo app",
initialMessage: "Create a todo app with authentication"
});
// 2. Wait for the AI response and get the preview URL
const response = await client.waitForResponse(project.id);
console.log(response.content); // AI's response text
console.log(response.messageId); // AI message ID
console.log(response.previewUrl); // Preview URL for the project
// 3. Send a follow-up chat message
await client.chat(project.id, {
message: "Add a footer",
});
// 4. Send a message with file attachments
import { readFile } from "fs/promises";
const imageData = await readFile("design.png");
await client.chat(project.id, {
message: "Update the hero section to match this design",
files: [{ name: "design.png", data: imageData, type: "image/png" }],
});
// 5. Publish the project and get the live URL
await client.publish(project.id);
const published = await client.waitForProjectPublished(project.id);
console.log(published.url); // Live public URLRemixing a project at a specific message
const client = new LovableClient({ apiKey: "lov_your-api-key" });
// Remix a project at the state just before a specific message
const jobId = await client.remixProject("source-project-id", {
workspaceId: "target-workspace-id",
messageId: "message-id-to-snapshot-at",
// remixMode: "including", // use "including" to keep the message and its AI response
includeHistory: true,
includeCustomKnowledge: true,
});
// Wait for the remix to complete
const { projectId } = await client.waitForRemix("source-project-id", jobId, {
onProgress: (status, step) => console.log(`Remix: ${status}`, step),
});
console.log(`Remixed project: ${projectId}`);
// Send a follow-up message to the remixed project
await client.chat(projectId, { message: "Add dark mode" });
const response = await client.waitForResponse(projectId);Continuation override
The continuation option on chat() overrides prompt cache reuse behavior. API-key auth only.
| Value | Effect |
| --- | --- |
| "force" | Skip all checks, force cache reuse |
| "fresh_build" | Force full prompt rebuild |
| "allow_expired_cache" | Skip expiry check only |
API Reference
LovableClient
Constructor
new LovableClient(options: LovableClientOptions)apiKey(required): Your Lovable API keybaseUrl(optional): Override the default API base URL
Methods
listWorkspaces(): Promise<WorkspaceWithMembership[]>
List all workspaces the authenticated user has access to.
getWorkspace(workspaceId: string): Promise<WorkspaceWithMembership>
Get a specific workspace by ID.
listProjects(workspaceId: string, options?): Promise<ProjectResponse[]>
List projects in a workspace.
Options:
limit(optional): Maximum number of projects to returnvisibility(optional): Filter by visibility ("all"|"personal"|"public"|"workspace")
createProject(workspaceId: string, options): Promise<ProjectResponse>
Create a new project in a workspace.
Options:
description(required): Project descriptiontechStack(optional): Technology stack (e.g.,"react")visibility(optional): Project visibility ("draft"|"private"|"public")templateProjectId(optional): ID of a template project to cloneinitialMessage(optional): Initial chat message to send to the AI agentfiles(optional): Array of files to attach (browserFileobjects orFileInputobjects)
chat(projectId: string, options): Promise<void>
Send a chat message to a project's AI agent.
Options:
message(required): The message to sendfiles(optional): Array of files to attach (browserFileobjects orFileInputobjects)chatOnly(optional): If true, only chat without making code changescontinuation(optional): Override prompt cache continuation behavior ("force"|"fresh_build"|"allow_expired_cache"). API-key auth only. See Continuation override
Note: This is an asynchronous operation. The API accepts the message and processes it in the background. Use waitForResponse() to wait for the AI's reply.
waitForResponse(projectId: string, options?): Promise<ChatResponse>
Wait for the AI's response to a chat message. Connects to the project's message stream (SSE) and returns the full response once complete.
Use this after chat() or after createProject() with initialMessage.
Returns:
content(string): The AI's full response textmessageId(string): The AI message IDpreviewUrl(string): The project's preview URL
Options:
timeout(optional): Maximum time to wait in ms (default: 300000 = 5 minutes)
Throws an error if the stream fails or timeout is reached.
getPreviewUrl(projectId: string): string
Get the preview URL for a project. This is a synchronous method that constructs the URL from the project ID.
publish(projectId: string, options?): Promise<DeploymentResponse>
Publish (deploy) a project to make it publicly accessible. The deployment runs asynchronously — use waitForProjectPublished() to wait for completion.
Options:
name(optional): Custom slug for the published URL
Returns:
status(string): Deployment statusdeployment_id(string): The deployment IDurl(string): The published URL (may not be available until deployment completes)
getPublishedUrl(projectId: string): Promise<string | null>
Get the published URL for a project, or null if not published. Fetches the latest project details to check publication status.
waitForProjectReady(projectId: string, options?): Promise<ProjectResponse>
Wait for a project to reach "completed" status. Projects start in "in_progress" status while being created/built.
Options:
pollInterval(optional): Time between polls in ms (default: 2000)timeout(optional): Maximum time to wait in ms (default: 300000 = 5 minutes)onProgress(optional): Callback for status updates
Throws an error if the project fails or timeout is reached.
waitForProjectPublished(projectId: string, options?): Promise<ProjectResponse>
Wait for a project to be published (deployed) and have a live URL.
Options:
pollInterval(optional): Time between polls in ms (default: 3000)timeout(optional): Maximum time to wait in ms (default: 600000 = 10 minutes)onProgress(optional): Callback for status updates
Throws an error if timeout is reached.
remixProject(sourceProjectId: string, options): Promise<string>
Remix (fork) an existing project, optionally at a specific message point in time.
When messageId is provided, the remix captures the project state as it was just before that message was processed (default remixMode: "before"). Set remixMode: "including" to include the message and its AI response in the remix. Without messageId, the full current state is remixed.
Returns the remix job ID for polling with waitForRemix().
Options:
workspaceId(required): Target workspace for the new projectmessageId(optional): Message ID to snapshot at — by default the remix reflects the project state just before this messageremixMode(optional):"before"(default) captures state before the message;"including"captures state after the message and its AI responseincludeHistory(optional, default:false): Whether to preserve chat historyincludeCustomKnowledge(optional, default:false): Whether to copy custom instructions/knowledgeinitialMessage(optional): Initial chat message to send after remix completesskipInitialRemixMessage(optional, default:false): When true, suppresses the default "I've successfully remixed this project" messageskipIntegrations(optional, default:false): When true, skips copying integrations to the remixed project
waitForRemix(sourceProjectId: string, jobId: string, options?): Promise<RemixResult>
Wait for a remix operation to complete. Polls until the job finishes.
Returns:
projectId(string): The ID of the newly created project
Options:
pollInterval(optional): Time between polls in ms (default: 2000)timeout(optional): Maximum time to wait in ms (default: 300000 = 5 minutes)onProgress(optional): Callback with(status, step?)for progress updates
Throws an error if the remix fails or timeout is reached.
inviteCollaborator(workspaceId: string, options): Promise<WorkspaceMembershipResponse>
Invite a user to a workspace.
Options:
email(required): Email address of the user to inviterole(optional): Role to assign ("admin"|"collaborator"|"member"|"viewer")
listWorkspaceMembers(workspaceId: string): Promise<WorkspaceMembershipResponse[]>
List all members of a workspace.
removeWorkspaceMember(workspaceId: string, userId: string): Promise<void>
Remove a member from a workspace.
getProject(projectId: string): Promise<ProjectResponse>
Get project details by ID.
Types
The SDK exports TypeScript types for all API responses. See src/types.ts for the full list.
import type {
WorkspaceWithMembership,
ProjectResponse,
CreateProjectOptions,
ChatResponse,
ContinuationOverride,
FileInput,
RemixProjectOptions,
// ... etc
} from "@lovable.dev/sdk";FileInput
For Node.js or non-browser environments, use FileInput instead of the browser File API:
interface FileInput {
name: string; // Original file name (e.g., "screenshot.png")
data: Blob | ArrayBuffer | Uint8Array; // File contents
type: string; // MIME type (e.g., "image/png")
}ContinuationOverride
Controls prompt cache continuation behavior for a message:
type ContinuationOverride = "force" | "fresh_build" | "allow_expired_cache";"force"— skip all continuation checks (force continuation)"fresh_build"— force a full prompt rebuild from scratch"allow_expired_cache"— skip cache expiry check but respect other continuation checks
