> ## Documentation Index
> Fetch the complete documentation index at: https://docs.syncsnap.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# useSyncsnapJob

> Hook to create a job and wait for completion (server-side wait)

# useSyncsnapJob

`useSyncsnapJob` creates a transfer job, then calls your backend's **wait** endpoint. The server polls until the job completes or fails and returns the final job plus a **result** (e.g. presigned download URL or a custom payload from your server's `onCompleted` callback). The hook passes that result to your `onCompleted(job, result)`. It powers `SyncsnapUploadButton` and can be used on its own for custom UIs.

## Basic usage

```tsx theme={null}
const { jobId, status, start, isWaiting, error, onCompleted } = useSyncsnapJob({
  onCompleted: (job, result) => {
    // result is whatever your server onCompleted returned (or the presigned URL when no callback)
    if (result && typeof result === "object" && "downloadUrl" in result)
      console.log("Download:", (result as { downloadUrl: string }).downloadUrl);
  },
});

return (
  <button onClick={() => start()} disabled={isWaiting}>
    {isWaiting ? "Waiting for upload..." : "Start transfer"}
  </button>
);
```

* Call **start()** to create a job and call the wait endpoint (server does the polling).
* **jobId** is set once the job is created; use it with [SyncsnapQrCode](/react/syncsnap-qr-code) or [createUploadUrl](/react/create-upload-url).
* **status** is the current job status; **isWaiting** is true while the wait request is in flight.
* **onCompleted(job, result)** runs when the job finishes; **result** is what your server's `onCompleted` returned, or the presigned download URL when no callback is set.

## Options

| Option | Type | Default | Description |
| - | - | - | - |
| `createJobUrl` | `string` | `"/api/syncsnap/job"` | URL for POST to create a job. |
| `getJobUrl` | `(jobId: string) => string` | `id => "/api/syncsnap/job/" + id` | URL for GET job status. |
| `getWaitForCompletionUrl` | `(jobId: string) => string` | `id => getJobUrl(id) + "/wait"` | URL for the server's wait endpoint (server polls until job completes). |
| `waitTimeoutMs` | `number` | `120000` | Timeout passed to the wait endpoint (ms). |
| `waitIntervalMs` | `number` | `2000` | Poll interval passed to the wait endpoint (ms). |
| `autoStart` | `boolean` | `false` | If true, call start() once on mount. |
| `onJobCreated` | `(job: CreateJobResponse) => void` | — | Called when the job is created. |
| `onCompleted` | `(job: Job, result?: unknown) => void` | — | Called when job completes or fails; result is server's onCompleted return (or presigned URL). |
| `onError` | `(error: Error) => void` | — | Called on create or wait errors. |

## Return value

| Property | Type | Description |
| - | - | - |
| `job` | `Job \| null` | Current job object, or null before create / after completion. |
| `jobId` | `string \| null` | Job ID when available. |
| `status` | `JobStatus \| null` | Current status. |
| `error` | `Error \| null` | Last error from create or wait. |
| `isWaiting` | `boolean` | True while the wait request is in flight. |
| `start` | `() => Promise<void>` | Create job and call wait endpoint. |
| `reset` | `() => void` | Abort wait, clear state, reset error. |

## Custom URLs

Use a different API base path:

```tsx theme={null}
useSyncsnapJob({
  createJobUrl: "/api/transfer/job",
  getJobUrl: (id) => `/api/transfer/job/${id}`,
  getWaitForCompletionUrl: (id) => `/api/transfer/job/${id}/wait`,
  onCompleted: (job, result) => { /* ... */ },
});
```

## Wait timeout and interval

The client sends `timeoutMs` and `intervalMs` as query params to the wait endpoint. Override the defaults:

```tsx theme={null}
useSyncsnapJob({
  waitTimeoutMs: 60000,
  waitIntervalMs: 3000,
  onCompleted: (job, result) => { /* ... */ },
});
```

## Auto-start

Create and call the wait endpoint as soon as the component mounts:

```tsx theme={null}
const { jobId, status } = useSyncsnapJob({ autoStart: true });
```

Use with care (e.g. dedicated page) so you don't create jobs unnecessarily.

## Reset

Call **reset()** to abort the wait and clear state (e.g. when the user closes the dialog):

```tsx theme={null}
const { start, reset } = useSyncsnapJob();

const handleClose = () => {
  reset();
};
```

## API reference

Full types: [useSyncsnapJob (API)](/api-reference/react-use-syncsnap-job).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.