# Save and close cleanly

`Job.Save` writes the active job to a `.sg` file. The `filePath` works
like Save As — pass any path you want; the file is created (or
overwritten) at that location. Wrap the work in `try / finally` so
`Job.Close` runs even if a step in the middle throws, otherwise the
service is left holding an active job and the next `Open` will
return `409`.

The snippet below opens the `Portal Frame.SG` sample, saves it as a
new file on the desktop, and closes the job — useful as a template
for any "open something, save it as something else" workflow.

<CodeTabs>
```csharp title="C#"
using SpaceGassApi;
using SpaceGassApi.Models;

var savePath = Path.Combine(
    Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
    "PortalFrameCopy.sg");

var client = SpaceGassApiClient.CreateClient("http://localhost:34560");

try
{
    await client.Job.OpenSample.PostAsync(
        new OpenSampleRequest { FileName = "Portal Frame.SG" });

    // ...modify the model however you like...

    await client.Job.Save.PostAsync(
        new SaveJobRequest { FilePath = savePath });
    Console.WriteLine($"Saved to {savePath}");
}
finally
{
    await client.Job.Close.PostAsync();
}
```

```python title="Python"
import os
from space_gass_api import SpaceGassApiClient
import space_gass_api.models as models

save_path = os.path.join(
    os.path.expanduser("~/Desktop"),
    "PortalFrameCopy.sg",
)

client = SpaceGassApiClient.create_client("http://localhost:34560")

try:
    await client.job.open_sample.post(
        models.OpenSampleRequest(file_name="Portal Frame.SG"))

    # ...modify the model however you like...

    await client.job.save.post(
        models.SaveJobRequest(file_path=save_path))
    print(f"Saved to {save_path}")
finally:
    await client.job.close.post()
```

```bash title="curl"
# Open the sample
curl -X POST http://localhost:34560/api/v1/job/open-sample \
  -H "Content-Type: application/json" \
  -d '{"fileName": "Portal Frame.SG"}'

# ...modify the model however you like...

curl -X POST http://localhost:34560/api/v1/job/save \
  -H "Content-Type: application/json" \
  -d '{"filePath": "C:\\Users\\you\\Desktop\\PortalFrameCopy.sg"}'

curl -X POST http://localhost:34560/api/v1/job/close
```
</CodeTabs>

If you want to save to the path the job was originally opened from,
omit `filePath` — the API saves over the original. (Sample projects
opened with `Job.OpenSample` are unsaved and have no original path,
so you must supply one.)

## See also

- [File Handling](/guides/file-handling) — open, save, force-open,
  status, and the full set of file lifecycle endpoints.
- [Concepts — The Active Job](/concepts#the-active-job)
