Attachment Content

Attachment content access - generate URLs and fetch content

JSON format

Content are represented as JSON objects with the following properties:

NameTypeRead-onlyMandatoryDescription
content_urlstringfalsefalse

Content URL resource representation

Get Attachment Content

  • GET /api/v2/attachment_content/{attachment_id}?token={token}

Fetches actual attachment content using an ephemeral token.

This endpoint:

  • Validates the JWT token
  • Checks IP restrictions (if configured)
  • Returns headers that direct edge proxy (Zorg) to fetch content from S3
  • Redirects to permanent URL if token is expired or already used

Response headers guide the edge proxy to rewrite the response with S3 content.

Parameters

NameTypeInRequiredDescription
tokenstringQuerytrueJWT token from Get Content URL response
attachment_idstringPathtrueULID of the attachment

Code Samples

Curl
curl --request GET https://p998.zdusercontent.com/api/v2/attachment_content/01HSEBFMDSF2AHZQSYP307QVBE?token=eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIiwidHlwIjoiSldUIn0..d4xR9hX_nuMQAzVR.AzVRy2u7-CRqq2gAfwI2eg.6XEFJiX5JT-RvIfRyB5cQA \--header "Authorization: Bearer ${authToken}" \--header "Content-Type: application/json"
Go
import (	"fmt"	"io"	"net/http")
func main() {	url := "https://p998.zdusercontent.com/api/v2/attachment_content/01HSEBFMDSF2AHZQSYP307QVBE?token=eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIiwidHlwIjoiSldUIn0..d4xR9hX_nuMQAzVR.AzVRy2u7-CRqq2gAfwI2eg.6XEFJiX5JT-RvIfRyB5cQA"	method := "GET"	req, err := http.NewRequest(method, url, nil)
	if err != nil {		fmt.Println(err)		return	}	req.Header.Add("Authorization", "Bearer ${authToken}")	req.Header.Add("Content-Type", "application/json")
	client := &http.Client {}	res, err := client.Do(req)	if err != nil {		fmt.Println(err)		return	}	defer res.Body.Close()
	body, err := io.ReadAll(res.Body)	if err != nil {		fmt.Println(err)		return	}	fmt.Println(string(body))}
Java
import com.squareup.okhttp.*;OkHttpClient client = new OkHttpClient();HttpUrl.Builder urlBuilder = HttpUrl.parse("https://p998.zdusercontent.com/api/v2/attachment_content/01HSEBFMDSF2AHZQSYP307QVBE")		.newBuilder()		.addQueryParameter("token", "eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIiwidHlwIjoiSldUIn0..d4xR9hX_nuMQAzVR.AzVRy2u7-CRqq2gAfwI2eg.6XEFJiX5JT-RvIfRyB5cQA");
Request request = new Request.Builder()		.url(urlBuilder.build())		.method("GET", null)		.addHeader("Authorization", "Bearer ${authToken}")		.addHeader("Content-Type", "application/json")		.build();Response response = client.newCall(request).execute();
Nodejs
var axios = require('axios');
var config = {  method: 'GET',  url: 'https://p998.zdusercontent.com/api/v2/attachment_content/01HSEBFMDSF2AHZQSYP307QVBE',  headers: {	'Authorization': 'Bearer ${authToken}',	'Content-Type': 'application/json',  },  params: {    'token': 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIiwidHlwIjoiSldUIn0..d4xR9hX_nuMQAzVR.AzVRy2u7-CRqq2gAfwI2eg.6XEFJiX5JT-RvIfRyB5cQA',  },};
axios(config).then(function (response) {  console.log(JSON.stringify(response.data));}).catch(function (error) {  console.log(error);});
Python
import requests
url = "https://p998.zdusercontent.com/api/v2/attachment_content/01HSEBFMDSF2AHZQSYP307QVBE?token=eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIiwidHlwIjoiSldUIn0..d4xR9hX_nuMQAzVR.AzVRy2u7-CRqq2gAfwI2eg.6XEFJiX5JT-RvIfRyB5cQA"headers = {	"Authorization": "Bearer ${authToken}",	"Content-Type": "application/json",}
response = requests.request(	"GET",	url,	headers=headers)
print(response.text)
Ruby
require "net/http"uri = URI("https://p998.zdusercontent.com/api/v2/attachment_content/01HSEBFMDSF2AHZQSYP307QVBE")uri.query = URI.encode_www_form("token": "eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIiwidHlwIjoiSldUIn0..d4xR9hX_nuMQAzVR.AzVRy2u7-CRqq2gAfwI2eg.6XEFJiX5JT-RvIfRyB5cQA")request = Net::HTTP::Get.new(uri, "Authorization": "Bearer ${authToken}", "Content-Type": "application/json")response = Net::HTTP.start uri.hostname, uri.port, use_ssl: true do |http|	http.request(request)end

Example response(s)

200 OK
// Status 200 OK
{}
302 Found
// Status 302 Found
{}
400 Bad Request
// Status 400 Bad Request
{  "errors": [    {      "code": "BadRequest",      "detail": "invalid JWT in request",      "title": "Bad Request"    }  ]}
403 Forbidden
// Status 403 Forbidden
{  "errors": [    {      "code": "Forbidden",      "detail": "IP not authorized to access this resource",      "title": "Forbidden"    }  ]}
404 Not Found
// Status 404 Not Found
{  "errors": [    {      "code": "NotFound",      "detail": "not found",      "title": "Not Found"    }  ]}