Skip to main content

Quickstart Tutorial

Protect your first image and get back its SignatureID. The tutorial takes about 10 minutes.

Steps​

  1. Get an access token.
  2. Submit an image.
  3. Poll the job until it completes.
  4. Download the protected image.

Before you start​

  • A Client ID and Client Secret from SASHA (Prerequisites)
  • A JPEG or PNG image, as a public URL or a local file
  • A terminal
tip

This tutorial polls for job status. In production, set up callbacks instead: SASHA posts the finished job to your endpoint, so your service makes no status requests.

gRPC prerequisites

For gRPC you also need a gRPC client such as nice-grpc (external link), and client code generated from the SASHA .proto files.

Step 1: Get an access token​

Exchange your client credentials for an access token.

Replace YOUR_CLIENT_ID and YOUR_CLIENT_SECRET with your own credentials:

curl https://partner.api.sasha.eu/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-u "YOUR_CLIENT_ID:YOUR_CLIENT_SECRET" \
-d "grant_type=client_credentials"

Response:

{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600
}
info

Keep the access_token value for the next steps. The token expires after expires_in seconds.

Step 2: Submit the image​

Submit the image URL to the Partner API. SASHA fetches the image and returns a job.

curl https://partner.api.sasha.eu/signature/embed \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"media_url": "https://developer.sasha.eu/img/sasha-logo-wall.jpeg",
"media_mime_type": "image/jpeg"
}'

Response:

{
"job": {
"job_id": "44cab986-0385-470a-8e5c-c657b0543d19",
"type": "embed-signature",
"status": "pending",
"created_at": "2025-10-07T12:00:00Z",
"updated_at": "2025-10-07T12:00:00Z"
}
}
info

Keep the job_id value. Step 3 uses it to read the job status.

Alternative: upload the file directly

To send a local file, use multipart/form-data (REST) or the EmbedSignatureFromData streaming method (gRPC). See Embed Signature.

Step 3: Poll the job​

Read the job every 2 seconds until status is completed. Most jobs complete within 1 second.

curl https://partner.api.sasha.eu/jobs/44cab986-0385-470a-8e5c-c657b0543d19 \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response (while processing):

{
"job_id": "44cab986-0385-470a-8e5c-c657b0543d19",
"type": "embed-signature",
"status": "in_progress",
"created_at": "2025-10-07T12:00:00Z",
"updated_at": "2025-10-07T12:00:01Z"
}

Response (when complete):

{
"job_id": "44cab986-0385-470a-8e5c-c657b0543d19",
"type": "embed-signature",
"status": "completed",
"output_url": "https://storage.sasha.eu/protected/abc123.jpg",
"output_url_expires_at": "2025-10-07T13:00:00Z",
"signature_id": "12345678901234567890",
"creator_id": 123,
"created_at": "2025-10-07T12:00:00Z",
"updated_at": "2025-10-07T12:00:05Z"
}

Step 4: Download the protected image​

Download the image from output_url.

curl -o protected-image.jpg "https://storage.sasha.eu/protected/abc123.jpg"
The URL expires

output_url stops working at the time in output_url_expires_at. Download the image before then.

Result​

You now have:

  • job_id — the identifier of the embed job
  • signature_id — the public handle for this Signature
  • creator_id — the CreatorID of the partner that protected the image
  • A protected image that looks identical to the original and carries the Signature

Look the Signature up​

Confirm the Signature is in the image by looking it up.

curl https://partner.api.sasha.eu/signature/lookup \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"media_url": "[USE_OUTPUT_URL_FROM_STEP_3]",
"media_mime_type": "image/jpeg"
}'

Replace [USE_OUTPUT_URL_FROM_STEP_3] with the output_url from Step 3.

The signature_id the lookup returns matches the one from your embed job.

Common issues​

401 UnauthorizedThe token expired, or the credentials are wrong. Request a new token.
400 Bad Request, media_url is requiredSend media_url and media_mime_type in a JSON body.
Job status is failed, error unsupported_formatConvert the image to JPEG or PNG.
404 Not Found on output_urlThe URL expired. Read output_url_expires_at, then run the embed job again.

Next steps​

Before you go to production
  1. Replace polling with callbacks.
  2. Cache the access token. Renew it 60 seconds before expires_in.
  3. Retry a failed job only on failed_to_fetch_from_url and internal.