Signed URLs¶
A signed URL is a normal web link with an embedded cryptographic signature attached. Anyone who has the link can access the resource at that URL — but only until the link expires. After expiry the link stops working automatically.
This lets you share a file from a private site with someone who does not have an ECMWF account, without making the entire site public or managing their access individually.
When to use signed URLs¶
- You want to share a single file from a private site publicly, temporarily.
- You are sending a download link in an email or a report.
- You need an external service to pull a file from your site without credentials.
Getting a content manager¶
Signed URL operations require a SiteContentManagement instance with admin rights over the site:
from sites.sdk.sites import Site, Authenticator
site = Site.from_space_and_name(space='docs', name='my-project')
content_manager = site.get_content_manager(
authenticator=Authenticator.from_token(token='<admin_site_bearer_token>')
)
Generating a signed URL¶
from sites.sdk.sites.utils import SiteAccessPermission
result = content_manager.generate_signed_url(
target_url='https://sites.ecmwf.int/docs/my-project/reports/2026-Q1.pdf',
duration=3600, # valid for 1 hour (3600 seconds)
permission=SiteAccessPermission.Read
)
signed_link = result['data']['url']
print(signed_link)
# https://sites.ecmwf.int/docs/my-project/reports/2026-Q1.pdf?sig=abc123...
target_url must be the full, absolute URL to the resource on the Sites platform.
Common duration values:
| Duration (seconds) | Human-readable |
|---|---|
3600 |
1 hour |
86400 |
1 day |
604800 |
7 days |
Permission values:
SiteAccessPermission.Read # link can only read/download the resource
SiteAccessPermission.ReadWrite # link can also write (advanced use case)
Verifying a signed URL¶
Before consuming a signed URL you can verify that it is still valid and has not expired:
verification = content_manager.verify_signed_url(
url='https://sites.ecmwf.int/docs/my-project/reports/2026-Q1.pdf?sig=abc123...'
)
print(verification)
# {'data': {'valid': True, 'permission': 'r', 'expiry': '2026-03-16T11:00:00'}, 'status': 'OK'}
If the URL has expired or was not produced by this site, the response will indicate it is invalid.
End-to-end example¶
The script below generates a signed URL, prints it, and then verifies it:
from sites.sdk.sites import Site, Authenticator
from sites.sdk.sites.utils import SiteAccessPermission
site = Site.from_space_and_name(space='docs', name='my-project')
mgr = site.get_content_manager(
authenticator=Authenticator.from_token(token='<admin_site_bearer_token>')
)
base_url = 'https://sites.ecmwf.int'
file_path = 'reports/annual-report-2026.pdf'
full_url = f'{base_url}/{site.custom_space}/{site.site_name}/{file_path}'
# Generate the link — valid for 24 hours
result = mgr.generate_signed_url(
target_url=full_url,
duration=86400,
permission=SiteAccessPermission.Read
)
signed_url = result['data']['url']
print('Share this link:')
print(signed_url)
# Verify the link is valid before sending it out
verification = mgr.verify_signed_url(url=signed_url)
if verification['data']['valid']:
print('Link is valid until', verification['data']['expiry'])
else:
print('Link is not valid!')
What's next?¶
- Access Tokens — for persistent API access rather than one-off share links
- Content Management — uploading and downloading files
- API Reference — quick method reference