Signed URLs
Signed URLs allow you to grant secure, temporary access to specific resources within the Euler platform. These URLs are programmatically generated by your application and include cryptographic signatures that verify their authenticity.
When Should You Use Signed URLs?
Signed URLs are useful when you want to:
- Provide temporary, controlled access to protected resources (e.g., print jobs).
- Securely share resources with external systems or users, while ensuring the access is limited in time and scope.
Examples of Use Cases
- Temporary access to print job data: Share live print job data with a client without adding them to your organization.
- Access to Data Reports: Allow external tools or teams to access specific reports with an expiring URL.
- One-Time Actions: Grant time-limited access to perform a single operation (e.g., a data export).
Supported Routes for Signed URLs
Signed URLs can be used with both backend API routes and specific frontend routes to securely access resources. Below is a list of the supported routes:
API Routes
All documented /api/* routes support Signed URLs. Refer to the API Documentation for details on specific endpoints.
Frontend Routes
The following frontend routes support Signed URLs (the method should be set to GET):
/app/[org-slug]/print/embed/[print-id]/app/[org-slug]/print/embed/ref/[device-slug]/[print-path]/app/[org-slug]/print/simple/[print-id]/app/[org-slug]/print/simple/ref/[device-slug]/[print-path]
If you're unsure whether a route supports Signed URLs or need assistance, feel free to contact us at hello@euler3d.com.
Generating signed URLs
Euler empowers you to generate Signed URLs directly within your application. This approach offers numerous advantages, with the most significant being efficiency and control. By delegating URL generation to you, there's no need to make an API request to our servers, enabling your application to create these URLs instantly and dynamically as needed.
This does mean, however, that the responsibility for implementing the signing logic and integrating it into your application lies with you. Fortunately, this is a straightforward task, and we've provided sample implementations in popular programming languages below to help you get started.
Create an API Token
To create an API token, navigate to the Integrations & API page in your Euler dashboard. Click the Create Token button to start the process. Optionally, set an expiry date for the token to ensure it becomes invalid after a specified time. Once you're ready, click Create to generate the token.

Never hard-code API tokens directly into your codebase. Instead, store them securely using environment variables or a secrets manager.
After creation, you will see the token details, including the Token ID and the Token Secret. This is the only time the token secret will be visible, so be sure to copy it and store it securely. If you prefer, you can use the Copy as Environment Variables button to generate a .env-compatible list of variables, which you can paste directly into your environment configuration file.
EULER_API_TOKEN_ID=01JEXAMPLECREDID
EULER_API_TOKEN_SECRET=your_api_secret_hereImplement the Signing Logic
We've implemented the signing logic in a few different languages, but the logic is straightforward and can be implemented in most programming languages without relying on external libraries. If your preferred programming language is missing from our examples, don't hesitate to reach out to us at hello@euler3d.com. We're happy to help!
import hmac
import hashlib
from datetime import datetime, timedelta, timezone
from urllib.parse import urlencode, urlparse, urlunparse, parse_qs
def create_signed_url(credential_id, secret, url, ttl_seconds, method="GET"):
if ttl_seconds > 864000: # 10 days in seconds
raise ValueError("TTL exceeds the maximum allowed value of 10 days.")
parsed_url = urlparse(url)
path = parsed_url.path
query_params = parse_qs(parsed_url.query)
# Sort query parameters by key
sorted_query = "&".join(f"{key}={','.join(sorted(value))}" for key, value in sorted(query_params.items()))
signed_at = datetime.now(timezone.utc)
expires_at = signed_at + timedelta(seconds=ttl_seconds)
algorithm = "sha256"
# Get timestamps as seconds
signed_at = int(signed_at.timestamp())
expires_at = int(expires_at.timestamp())
# Generate HMAC hash
payload = f"{method.upper()}|{path}|{sorted_query}|{signed_at}|{expires_at}"
hmac_hash = hmac.new(secret.encode(), payload.encode(), hashlib.sha256).hexdigest()
# Add query parameters
query_params.update({
"euler-sig-algorithm": algorithm,
"euler-sig-cred": credential_id,
"euler-sig-signed-at": signed_at,
"euler-sig-expires-at": expires_at,
"euler-sig-hash": hmac_hash,
})
signed_url = urlunparse(parsed_url._replace(query=urlencode(query_params, doseq=True)))
return signed_url
# ========= EXAMPLE USAGE =========
if __name__ == '__main__':
signed_url = create_signed_url(
credential_id="__API_TOKEN_ID__",
secret="__API_TOKEN_SECRET__",
url="https://www.euler3d.com/api/resource?type=example",
ttl_seconds=3600, # 1 hour
method="GET"
)
print(signed_url)Test the URL
Take the output from your URL signing code and paste it into a web browser or API client to validate that it works. Be sure you're not already logged in to the Euler platform, as this might result in a false positive. Using incognito mode can help ensure a clean testing environment.
If a Signed URL isn't working, paste it into the Signed URL Debugger to troubleshoot issues with parameters or signatures.
Debugging Signed URLs
Euler provides a Signed URL Debugger to help you validate and troubleshoot your Signed URLs.

How to Use the Debugger
- Go to the Integrations & API page for your organization.
- Copy your Signed URL and paste it into the debugger input field.
- Click Debug to analyze the URL.
- The debugger will:
- Check the validity of each parameter (e.g.,
euler-sig-cred,euler-sig-algorithm). - Highlight any issues (e.g., an expired URL or an invalid signature).
- Provide helpful feedback for resolving problems.
- Check the validity of each parameter (e.g.,
The debugger is especially useful when implementing Signed URL support in your application or troubleshooting integration issues.
Best Practices for Signed URLs
- Short Expiration Times: Use a short TTL to minimize exposure. The shorter the URL's lifetime, the less risk of misuse.
- Secure Secrets: Keep API secrets safe and rotate them periodically.
- Test Regularly: Use the debugger to ensure your Signed URLs are working as expected.
How Signed URLs Work
A Signed URL is a regular URL with additional query parameters that include:
- Algorithm (
euler-sig-algorithm): Specifies the cryptographic hashing algorithm used (e.g.,sha256). - Credential ID (
euler-sig-cred): Identifies the API Token used to generate the URL. - Signed At (
euler-sig-signed-at): The timestamp when the URL was generated. - Expires At (
euler-sig-expires-at): The timestamp when the URL will expire. - Signature (
euler-sig-hash): A cryptographic hash generated using the API Token's secret, which ensures the URL's integrity.
When a Signed URL is accessed, the Euler platform verifies these parameters to ensure:
- The URL hasn't been tampered with.
- The signature matches the expected value.
- The URL is still valid (i.e., it hasn't expired).
Signed URL Specification
Each Signed URL must include the following parameters in the query string:
| Parameter | Description |
|---|---|
euler-sig-algorithm | The hashing algorithm used (must be sha256). |
euler-sig-cred | The unique ID of the API Token used to sign the URL. |
euler-sig-signed-at | The timestamp (in seconds) when the URL was created. |
euler-sig-expires-at | The timestamp (in seconds) when the URL will expire. |
euler-sig-hash | The SHA256 cryptographic hash generated from the payload <HTTP_METHOD>|<PATH>|<SORTED_QUERY_PARAMETERS>|<SIGNED_AT>|<EXPIRES_AT> using your API Token's secret. |
Signed URL flow
Learn More
- API Tokens Guide: Learn how to manage API Tokens, which are required to generate Signed URLs.
- Full API Reference: Explore detailed documentation for all available endpoints.
If you have any questions, reach out to Euler Support.