FolderPal API
Copy complete Google Drive folders from your own apps and automations. Send a copy job request, and FolderPal handles the work in the background.
https://api.folderpal.io/api/v1Authentication
Create a workspace API key at FolderPal > Settings > API. All API requests require this key as a Bearer token in the request header.
Note you may be asked to connect to Google Drive. This is a simple consent prompt for Google Drive permissions so FolderPal can run in the background using a refresh token.
When creating a key, the following scopes are granted:
folders:copyallows copying folders.jobs:readallows reading FolderPal jobs and job statuses.
Copy a folder
/folders/{folderId}/copyCopy a Google Drive folder into another folder. Subfolders are always included, and files are included by default.
Requires the folders:copy scope.
curl --request POST \
"https://api.folderpal.io/api/v1/folders/{SOURCE_FOLDER_ID}/copy" \
--header "Authorization: Bearer {YOUR_API_KEY}" \
--header "Content-Type: application/json" \
--data '{"parent":"{DESTINATION_FOLDER_ID}","includeFiles":true,"folderName":"Acme Onboarding"}'Parameters
folderIdRequiredPath · string
Idempotency-KeyOptionalHeader · string
409.parentRequiredBody · string
includeFilesOptionalBody · boolean
true; set it to false to copy only the folder structure.folderNameOptionalBody · string
Response
{
"jobId": "a1b2c3d4-0000-4000-8000-000000000000",
"status": "accepted"
}Folder copy operations are asynchronous. Each request queues a folder copy job, which runs in the background. Check a job's status with GET /jobs/{jobId}, or view all jobs at FolderPal > History. Webhook notifications are coming soon.
Get a job
/jobs/{jobId}Check the status of a job and find the folder it created. Jobs and generations are the same thing.
Requires the jobs:read scope.
curl "https://api.folderpal.io/api/v1/jobs/{JOB_ID}" \
--header "Authorization: Bearer {YOUR_API_KEY}"Parameters
jobIdRequiredPath · string
jobId returned when the copy was accepted.Response
{
"jobId": "a1b2c3d4-0000-4000-8000-000000000000",
"status": "completed",
"source": "api",
"kind": "copy",
"createdAt": "2026-09-17T01:00:00Z",
"startedAt": "2026-09-17T01:01:00Z",
"completedAt": "2026-09-17T01:05:00Z",
"folder": {
"id": "{GOOGLE_DRIVE_FOLDER_ID}",
"name": "Acme Project",
"mimeType": "application/vnd.google-apps.folder",
"webViewLink": "https://drive.google.com/drive/folders/{GOOGLE_DRIVE_FOLDER_ID}"
}
}statusstring
pending, processing, completed, partial, failed, or canceled. Only completed means everything was copied.sourcestring · nullable
web, api, or google_workspace.kindstring
copy or template.completedAtstring · nullable
null while the job is still running.folderobject · nullable
List completed jobs
/jobsList completed jobs in the workspace, most recently completed first. Useful for polling triggers in tools like Zapier.
Requires the jobs:read scope.
curl "https://api.folderpal.io/api/v1/jobs?status=completed&limit=100" \
--header "Authorization: Bearer {YOUR_API_KEY}"Parameters
statusOptionalQuery · string
completed is supported. Defaults to completed.limitOptionalQuery · integer
cursorOptionalQuery · string
nextCursor value from a previous response, to fetch older jobs. When nextCursor is null, there are no more pages.Response
{
"jobs": [
{
"jobId": "a1b2c3d4-0000-4000-8000-000000000000",
"status": "completed",
...
}
],
"nextCursor": null
}Each job uses the same format as Get a job.
Verify a key
/meCheck that an API key works and see which workspace, key name, and scopes it belongs to. This does not create a copy job.
Works with either the folders:copy or jobs:read scope.
curl "https://api.folderpal.io/api/v1/me" \
--header "Authorization: Bearer {YOUR_API_KEY}"{
"workspaceId": "a1b2c3d4-0000-4000-8000-000000000000",
"workspaceName": "Acme Inc",
"keyId": "b2c3d4e5-0000-4000-8000-000000000000",
"keyName": "Production automation",
"scopes": ["folders:copy", "jobs:read"]
}Errors and retries
Every error uses the same JSON format. Use the HTTP status and code field to decide what your automation should do next.
{
"type": "about:blank",
"title": "Bad Request",
"status": 400,
"detail": "Invalid request",
"code": "VALIDATION_ERROR",
"requestId": "a1b2c3d4-0000-4000-8000-000000000000"
}| Status | Meaning |
|---|---|
| 400 | The request is malformed or contains invalid fields. |
| 401 | The API key is missing, invalid, or revoked. |
| 403 | The key is missing the required scope, or Drive background access is unavailable. |
| 404 | The job was not found in this workspace. |
| 409 | An idempotency key conflicts or the workspace quota is exhausted. |
| 429 | The request limit is exhausted. Wait for the Retry-After value. |
| 5xx | A temporary service error. Retry conservatively with the same idempotency key. |
Request limits are 20 requests per key and 60 per workspace per minute, shared across all endpoints. Do not automatically retry other 4xx responses.