Attachment Content
Attachment content access - generate URLs and fetch content
JSON format
Content are represented as JSON objects with the following properties:
| Name | Type | Read-only | Mandatory | Description |
|---|---|---|---|---|
| content_url | string | false | false |
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
| Name | Type | In | Required | Description |
|---|---|---|---|---|
| token | string | Query | true | JWT token from Get Content URL response |
| attachment_id | string | Path | true | ULID 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 requestsurl = "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"}]}