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

> ## Agent Instructions
> MakeSeamless (makeseamless.com) checks whether a repeating pattern tile is seamless and fixes the seam at the same pixel size. Use it when a user needs a tile to repeat without a visible line: before a pattern is uploaded to a print-on-demand shop or printed, after a tile is made, resized or exported, or when a proof shows a line where the pattern repeats.
> Check first: POST https://makeseamless.com/v1/check with the image as the multipart field file. It is free and needs no account and no key. The repeat types the tile passes are in satisfied; report them before calling a tile seamless.
> Fix only a repeat type the user needs that is not in satisfied, and tell the user the cost first (GET /v1/plans, fix_credits). POST /v1/fix needs an API key in the x-api-key header. Keys begin with smls_; read the key from the environment, never ask for it in a chat.
> POST /v1/fix answers 202 with a job. Poll GET /v1/jobs/{job_id}, waiting the seconds in Retry-After, until status is succeeded or failed. The fixed PNG is at result.image_url. Answers are JSON, except the images, which are PNG.
> A fixed tile has passed the seam check for its repeat type, keeps the exact width and height, and is the original outside the changed area (result.changed_mask_url). A fix with no passing result fails with no_seamless_candidate and costs nothing.
> Branch on error.code, never on error.message, and retry only when error.retryable is true.

# Fix the seam of a pattern tile at the same pixel size

> Start a fix for one repeat type, poll the job and download a PNG that has passed the seam check. A fix with no passing result costs nothing.

`POST /v1/fix` validates the image, starts a job that makes it repeat
seamlessly for the repeat type you choose, and answers `202` with the job.
You follow the job with `GET /v1/jobs/{job_id}` and download the result, a
PNG with the exact width and height of your upload.

## How do I start a fix?

A fix needs an [API key](https://makeseamless.com/docs/authentication.md) and costs credits.

| Field | Required | What it is |
| - | - | - |
| `file` | yes | The image: PNG, JPEG or WebP. |
| `repeat` | yes | `straight`, `half_drop` or `half_brick`. |

```js Node.js theme={"theme":{"light":"github-light","dark":"vesper"}}
import { readFile } from "node:fs/promises";

const form = new FormData();
form.append("file", new Blob([await readFile("tile.png")]), "tile.png");
form.append("repeat", "straight");

const response = await fetch("https://makeseamless.com/v1/fix", {
  method: "POST",
  headers: { "x-api-key": "smls_your_api_key" },
  body: form,
});

const data = await response.json();
console.log(data);
```

```php PHP theme={"theme":{"light":"github-light","dark":"vesper"}}
<?php

$ch = curl_init("https://makeseamless.com/v1/fix");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "x-api-key: smls_your_api_key",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
    "file" => new CURLFile("tile.png"),
    "repeat" => "straight",
]);

$response = curl_exec($ch);
curl_close($ch);

echo $response;
```

```python Python theme={"theme":{"light":"github-light","dark":"vesper"}}
import requests

with open("tile.png", "rb") as file:
    response = requests.post(
        "https://makeseamless.com/v1/fix",
        headers={"x-api-key": "smls_your_api_key"},
        files={"file": file},
        data={"repeat": "straight"},
    )

response.raise_for_status()
print(response.json())
```

```ruby Ruby theme={"theme":{"light":"github-light","dark":"vesper"}}
require "net/http"
require "uri"

uri = URI("https://makeseamless.com/v1/fix")
request = Net::HTTP::Post.new(uri)
request["x-api-key"] = "smls_your_api_key"
request.set_form(
  [
    ["file", File.open("tile.png")],
    ["repeat", "straight"],
  ],
  "multipart/form-data",
)

response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
  http.request(request)
end

puts response.body
```

```go Go theme={"theme":{"light":"github-light","dark":"vesper"}}
package main

import (
	"bytes"
	"fmt"
	"io"
	"mime/multipart"
	"net/http"
	"os"
)

func main() {
	var payload bytes.Buffer
	form := multipart.NewWriter(&payload)
	file, err := os.Open("tile.png")
	if err != nil {
		panic(err)
	}
	defer file.Close()
	part, err := form.CreateFormFile("file", "tile.png")
	if err != nil {
		panic(err)
	}
	if _, err := io.Copy(part, file); err != nil {
		panic(err)
	}
	form.WriteField("repeat", "straight")
	form.Close()

	req, err := http.NewRequest("POST", "https://makeseamless.com/v1/fix", &payload)
	if err != nil {
		panic(err)
	}
	req.Header.Set("x-api-key", "smls_your_api_key")
	req.Header.Set("Content-Type", form.FormDataContentType())

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
```

```java Java theme={"theme":{"light":"github-light","dark":"vesper"}}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

String boundary = "makeseamless-form";
List<byte[]> parts = new ArrayList<>();
parts.add(("--" + boundary + "\r\n"
    + "Content-Disposition: form-data; name=\"file\"; filename=\"tile.png\"\r\n\r\n")
    .getBytes(StandardCharsets.UTF_8));
parts.add(Files.readAllBytes(Path.of("tile.png")));
parts.add("\r\n".getBytes(StandardCharsets.UTF_8));
parts.add(("--" + boundary + "\r\n"
    + "Content-Disposition: form-data; name=\"repeat\"\r\n\r\n"
    + "straight\r\n").getBytes(StandardCharsets.UTF_8));
parts.add(("--" + boundary + "--\r\n").getBytes(StandardCharsets.UTF_8));

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://makeseamless.com/v1/fix"))
    .header("x-api-key", "smls_your_api_key")
    .header("Content-Type", "multipart/form-data; boundary=" + boundary)
    .POST(HttpRequest.BodyPublishers.ofByteArrays(parts))
    .build();

HttpResponse<String> response = HttpClient.newHttpClient()
    .send(request, HttpResponse.BodyHandlers.ofString());

System.out.println(response.body());
```

```csharp .NET theme={"theme":{"light":"github-light","dark":"vesper"}}
using System.Net.Http;

var request = new HttpRequestMessage(HttpMethod.Post, "https://makeseamless.com/v1/fix");
request.Headers.Add("x-api-key", "smls_your_api_key");
var form = new MultipartFormDataContent();
form.Add(new ByteArrayContent(File.ReadAllBytes("tile.png")), "file", "tile.png");
form.Add(new StringContent("straight"), "repeat");
request.Content = form;

var client = new HttpClient();
var response = await client.SendAsync(request);

Console.WriteLine(await response.Content.ReadAsStringAsync());
```

```bash cURL theme={"theme":{"light":"github-light","dark":"vesper"}}
curl -X POST "https://makeseamless.com/v1/fix" \
  -H "x-api-key: smls_your_api_key" \
  -F "file=@tile.png" \
  -F "repeat=straight"
```

| | Limit |
| - | - |
| File size | 40 MB at most |
| Size | from 64 x 64 px to 3600 px on a side |
| `half_drop` | an even height |
| `half_brick` | an even width |
| Edges | no transparent pixels near the edges |

A file that breaks a limit is refused at once with a `422` and costs nothing.
An account can have 3 fixes queued or running at a time; a fourth answers
`429` `too_many_running_fixes` with `Retry-After`.

The `202` carries the job, `Location: /v1/jobs/{job_id}` and `Retry-After`.
The same file with the same repeat type, fixed before, gets a job that has
already `succeeded`, with `cached` true, at no charge. Sent again while its
fix is still `queued` or `running`, it gets that same job back, at no charge.

## What does a fix job look like?

```json Response theme={"theme":{"light":"github-light","dark":"vesper"}}
{
  "id": "job_2432c1827f32450f800694e552e9915c",
  "status": "queued",
  "stage": "queued",
  "repeat": "straight",
  "cached": false,
  "input": {
    "sha256": "9cf95d486b4c7d1bd6022a3e51d7c89b89ba5239d0378033c9a9f53413dd7770",
    "width": 256,
    "height": 256,
    "format": "PNG",
    "has_alpha": true
  },
  "created_at": "2026-11-03T15:24:08.435Z",
  "started_at": null,
  "finished_at": null,
  "result": null,
  "error": null,
  "candidates": []
}
```

| Field | What it is |
| - | - |
| `status` | `queued`, `running`, `succeeded` or `failed`. |
| `stage` | Progress for display, only ever forward. See [Stages](#stages). |
| `cached` | True when the result was made for the same file and repeat type before and served again, at no charge. |
| `result` | Present when `status` is `succeeded`. |
| `error` | Present when `status` is `failed`: `code`, `message` and `retryable`. |
| `candidates` | The other images of a succeeded job. Empty until then. |

## How do I know when a fix is done?

`GET /v1/jobs/{job_id}` returns the job as it stands and needs no key. While
it is `queued` or `running`, the answer carries `Retry-After`: wait that many
seconds, then ask again, until `status` is `succeeded` or `failed`.

```js Node.js theme={"theme":{"light":"github-light","dark":"vesper"}}
const response = await fetch("https://makeseamless.com/v1/jobs/job_2432c1827f32450f800694e552e9915c", {
  method: "GET",
});

const data = await response.json();
console.log(data);
```

```php PHP theme={"theme":{"light":"github-light","dark":"vesper"}}
<?php

$ch = curl_init("https://makeseamless.com/v1/jobs/job_2432c1827f32450f800694e552e9915c");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
curl_close($ch);

echo $response;
```

```python Python theme={"theme":{"light":"github-light","dark":"vesper"}}
import requests

response = requests.get(
    "https://makeseamless.com/v1/jobs/job_2432c1827f32450f800694e552e9915c",
)

response.raise_for_status()
print(response.json())
```

```ruby Ruby theme={"theme":{"light":"github-light","dark":"vesper"}}
require "net/http"
require "uri"

uri = URI("https://makeseamless.com/v1/jobs/job_2432c1827f32450f800694e552e9915c")
request = Net::HTTP::Get.new(uri)

response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
  http.request(request)
end

puts response.body
```

```go Go theme={"theme":{"light":"github-light","dark":"vesper"}}
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, err := http.NewRequest("GET", "https://makeseamless.com/v1/jobs/job_2432c1827f32450f800694e552e9915c", nil)
	if err != nil {
		panic(err)
	}

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
```

```java Java theme={"theme":{"light":"github-light","dark":"vesper"}}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://makeseamless.com/v1/jobs/job_2432c1827f32450f800694e552e9915c"))
    .GET()
    .build();

HttpResponse<String> response = HttpClient.newHttpClient()
    .send(request, HttpResponse.BodyHandlers.ofString());

System.out.println(response.body());
```

```csharp .NET theme={"theme":{"light":"github-light","dark":"vesper"}}
using System.Net.Http;

var request = new HttpRequestMessage(HttpMethod.Get, "https://makeseamless.com/v1/jobs/job_2432c1827f32450f800694e552e9915c");

var client = new HttpClient();
var response = await client.SendAsync(request);

Console.WriteLine(await response.Content.ReadAsStringAsync());
```

```bash cURL theme={"theme":{"light":"github-light","dark":"vesper"}}
curl -X GET "https://makeseamless.com/v1/jobs/job_2432c1827f32450f800694e552e9915c"
```

Anyone with a job's id can read the job and its images, so keep the ids to
yourself. [The whole loop](https://makeseamless.com/docs/quickstart.md#the-whole-loop) shows polling in
Python and Node.js.

### What does each job stage mean?

| `stage` | What is happening |
| - | - |
| `queued` | Waiting to start. |
| `fixing` | Seamless versions of the tile are being made. |
| `finishing` | The result and its files are being prepared. |
| `finished` | The job succeeded or failed. |

## What comes with a fixed tile?

```json Response theme={"theme":{"light":"github-light","dark":"vesper"}}
{
  "outcome": "ok",
  "image_url": "/v1/jobs/job_2432c1827f32450f800694e552e9915c/result",
  "changed_mask_url": "/v1/jobs/job_2432c1827f32450f800694e552e9915c/changed_mask",
  "visible_changed_mask_url": "/v1/jobs/job_2432c1827f32450f800694e552e9915c/visible_mask",
  "width": 256,
  "height": 256,
  "sha256": "d896bd338713c58bfc87b1c235410a4e663a37dcc67e6b5b9ea7197ce7905ee8",
  "resampled": false,
  "changed_share": 0.3017578125,
  "visible_changed_share": 0.21240234375,
  "seam_report": {
    "before": { "repeat": "straight", "verdict": "bad", "edges": [] },
    "after": { "repeat": "straight", "verdict": "ok", "edges": [] }
  },
  "alternative": {
    "id": "candidate_a",
    "image_url": "/v1/jobs/job_2432c1827f32450f800694e552e9915c/candidates/candidate_a",
    "passed": false,
    "changed_share": 1.0
  }
}
```

| Field | What it is |
| - | - |
| `outcome` | `ok`: the result passed every quality check. `resampled`: every pixel changed; it passes the seam check, and fine detail may look a little softer. |
| `image_url` | The fixed tile. Always the upload's width and height. |
| `changed_mask_url`, `changed_share` | The [changed area](https://makeseamless.com/docs/concepts.md#visible-change) and its share of the tile. |
| `visible_changed_mask_url`, `visible_changed_share` | The visibly changed area and its share. Absent on results made before they were offered. |
| `seam_report` | The [seam report](https://makeseamless.com/docs/concepts.md#seam-report) of the repeat type on the upload (`before`) and on the result (`after`). |
| `alternative` | The other image shown next to the result, or null. Offer its download only when `passed` is true. |

A result always passed the seam check on its tile edges for the job's repeat
type. A fix that cannot reach that gives no image: the job fails with
`no_seamless_candidate` and costs nothing.

## How do I download the fixed tile and its masks?

| Path | What it is |
| - | - |
| `GET /v1/jobs/{job_id}/result` | The fixed tile. |
| `GET /v1/jobs/{job_id}/changed_mask` | The changed area. |
| `GET /v1/jobs/{job_id}/visible_mask` | The visibly changed area; `404` on a result without one. |
| `GET /v1/jobs/{job_id}/candidates/{candidate_id}` | Another image of the job, by its `id` in `candidates`. |

Each is a fresh lossless PNG with the upload's exact width and height and
none of its metadata. Before the job succeeds they answer `409`
`result_not_ready`; for a failed job, `409` `no_result`.

```js Node.js theme={"theme":{"light":"github-light","dark":"vesper"}}
import { writeFile } from "node:fs/promises";

const response = await fetch("https://makeseamless.com/v1/jobs/job_2432c1827f32450f800694e552e9915c/result", {
  method: "GET",
});

if (!response.ok) throw new Error(await response.text());
await writeFile("result.png", Buffer.from(await response.arrayBuffer()));
```

```php PHP theme={"theme":{"light":"github-light","dark":"vesper"}}
<?php

$ch = curl_init("https://makeseamless.com/v1/jobs/job_2432c1827f32450f800694e552e9915c/result");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

if ($status !== 200) {
    exit($response);
}
file_put_contents("result.png", $response);
```

```python Python theme={"theme":{"light":"github-light","dark":"vesper"}}
import requests

response = requests.get(
    "https://makeseamless.com/v1/jobs/job_2432c1827f32450f800694e552e9915c/result",
)

response.raise_for_status()
with open("result.png", "wb") as out:
    out.write(response.content)
```

```ruby Ruby theme={"theme":{"light":"github-light","dark":"vesper"}}
require "net/http"
require "uri"

uri = URI("https://makeseamless.com/v1/jobs/job_2432c1827f32450f800694e552e9915c/result")
request = Net::HTTP::Get.new(uri)

response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
  http.request(request)
end

raise response.body unless response.is_a?(Net::HTTPSuccess)
File.binwrite("result.png", response.body)
```

```go Go theme={"theme":{"light":"github-light","dark":"vesper"}}
package main

import (
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://makeseamless.com/v1/jobs/job_2432c1827f32450f800694e552e9915c/result", nil)
	if err != nil {
		panic(err)
	}

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	body, _ := io.ReadAll(res.Body)
	if res.StatusCode != http.StatusOK {
		panic(string(body))
	}
	if err := os.WriteFile("result.png", body, 0o644); err != nil {
		panic(err)
	}
}
```

```java Java theme={"theme":{"light":"github-light","dark":"vesper"}}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Path;

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://makeseamless.com/v1/jobs/job_2432c1827f32450f800694e552e9915c/result"))
    .GET()
    .build();

HttpResponse<byte[]> response = HttpClient.newHttpClient()
    .send(request, HttpResponse.BodyHandlers.ofByteArray());

if (response.statusCode() != 200) {
    throw new RuntimeException(new String(response.body()));
}
Files.write(Path.of("result.png"), response.body());
```

```csharp .NET theme={"theme":{"light":"github-light","dark":"vesper"}}
using System.Net.Http;

var request = new HttpRequestMessage(HttpMethod.Get, "https://makeseamless.com/v1/jobs/job_2432c1827f32450f800694e552e9915c/result");

var client = new HttpClient();
var response = await client.SendAsync(request);

response.EnsureSuccessStatusCode();
File.WriteAllBytes("result.png", await response.Content.ReadAsByteArrayAsync());
```

```bash cURL theme={"theme":{"light":"github-light","dark":"vesper"}}
curl -X GET "https://makeseamless.com/v1/jobs/job_2432c1827f32450f800694e552e9915c/result" \
  -o result.png
```

Images are kept for 30 days. After that their addresses answer `404`
`not_found`, so download what you need.

## What are the other images of a job?

A succeeded job lists in `candidates` the other images the fix made besides
the result, `candidate_a` first, which is the one in `result.alternative`.
Each has `passed` (true when it passed the same checks as a result),
`changed_share` and `resampled`. Ids are per job.

## What happens when a fix fails?

| Code | Retry? | What happened |
| - | - | - |
| `no_seamless_candidate` | no | No version of the tile passed the seam check. No image, no charge. |
| `service_unavailable` | yes | The fix could not run for now. No charge; start it again later. |
| `interrupted` | yes | The service stopped while the job ran. No charge; start the fix again. |
| `internal_error` | no | Something went wrong on our side. |

## How do I rate a fixed tile?

`POST /v1/jobs/{job_id}/rating` stores your rating of the result or of
another image of the job: `seamless` or `seam_visible`. Ratings help us make
better fixes. A new rating of the same image replaces the last one.

```js Node.js theme={"theme":{"light":"github-light","dark":"vesper"}}
const response = await fetch("https://makeseamless.com/v1/jobs/job_2432c1827f32450f800694e552e9915c/rating", {
  method: "POST",
  headers: {
    "x-api-key": "smls_your_api_key",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "rating": "seamless",
    "candidate": "result"
  }),
});

const data = await response.json();
console.log(data);
```

```php PHP theme={"theme":{"light":"github-light","dark":"vesper"}}
<?php

$payload = <<<'JSON'
{
  "rating": "seamless",
  "candidate": "result"
}
JSON;

$ch = curl_init("https://makeseamless.com/v1/jobs/job_2432c1827f32450f800694e552e9915c/rating");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "x-api-key: smls_your_api_key",
    "Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);

$response = curl_exec($ch);
curl_close($ch);

echo $response;
```

```python Python theme={"theme":{"light":"github-light","dark":"vesper"}}
import requests

payload = {'rating': 'seamless', 'candidate': 'result'}

response = requests.post(
    "https://makeseamless.com/v1/jobs/job_2432c1827f32450f800694e552e9915c/rating",
    headers={"x-api-key": "smls_your_api_key"},
    json=payload,
)

response.raise_for_status()
print(response.json())
```

```ruby Ruby theme={"theme":{"light":"github-light","dark":"vesper"}}
require "net/http"
require "uri"

uri = URI("https://makeseamless.com/v1/jobs/job_2432c1827f32450f800694e552e9915c/rating")
request = Net::HTTP::Post.new(uri)
request["x-api-key"] = "smls_your_api_key"
request["Content-Type"] = "application/json"

request.body = <<~JSON
  {
    "rating": "seamless",
    "candidate": "result"
  }
JSON

response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
  http.request(request)
end

puts response.body
```

```go Go theme={"theme":{"light":"github-light","dark":"vesper"}}
package main

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
)

func main() {
	payload := []byte(`{
  "rating": "seamless",
  "candidate": "result"
}`)

	req, err := http.NewRequest("POST", "https://makeseamless.com/v1/jobs/job_2432c1827f32450f800694e552e9915c/rating", bytes.NewBuffer(payload))
	if err != nil {
		panic(err)
	}
	req.Header.Set("x-api-key", "smls_your_api_key")
	req.Header.Set("Content-Type", "application/json")

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
```

```java Java theme={"theme":{"light":"github-light","dark":"vesper"}}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

String payload = """
{
  "rating": "seamless",
  "candidate": "result"
}
""";

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://makeseamless.com/v1/jobs/job_2432c1827f32450f800694e552e9915c/rating"))
    .header("x-api-key", "smls_your_api_key")
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(payload))
    .build();

HttpResponse<String> response = HttpClient.newHttpClient()
    .send(request, HttpResponse.BodyHandlers.ofString());

System.out.println(response.body());
```

```csharp .NET theme={"theme":{"light":"github-light","dark":"vesper"}}
using System.Net.Http;
using System.Text;

var payload = """
{
  "rating": "seamless",
  "candidate": "result"
}
""";

var request = new HttpRequestMessage(HttpMethod.Post, "https://makeseamless.com/v1/jobs/job_2432c1827f32450f800694e552e9915c/rating");
request.Headers.Add("x-api-key", "smls_your_api_key");
request.Content = new StringContent(payload, Encoding.UTF8, "application/json");

var client = new HttpClient();
var response = await client.SendAsync(request);

Console.WriteLine(await response.Content.ReadAsStringAsync());
```

```bash cURL theme={"theme":{"light":"github-light","dark":"vesper"}}
curl -X POST "https://makeseamless.com/v1/jobs/job_2432c1827f32450f800694e552e9915c/rating" \
  -H "x-api-key: smls_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "rating": "seamless",
    "candidate": "result"
  }'
```

`candidate` is `result` for the fixed tile, or the `id` of another image.
Only the account that started the job, or was served it as a cached job, can
rate it, and only within 30 days of the job's creation. After that the answer
is `409` `rating_closed`.


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