Accessing end user uploaded attachments
If you've built a custom ticket form using the Ticketing API, accessing end user uploaded attachments requires a valid Zendesk session by default. This also applies to all attachments when Secure Downloads is enabled. Users on external websites don't have a Zendesk session, so attachment URLs cannot be accessed directly in the browser.
To serve these attachments on your website, create a proxy endpoint that requests the content_url with your OAuth access token on behalf of the user. Zendesk responds with a 302 and a Location header containing a temporary download URL. The proxy redirects the user's browser to this URL to download the file.
Attachment URLs returned by the Ticketing API in the content_url field should be routed through your proxy endpoint. For example:
https://yoursubdomain.zendesk.com/attachments/token/abc/?name=file.png
becomes:
https://yourserver.com/attachments/token/abc/?name=file.png
Node.js
app.get('/attachments/token/:token/', async (req, res) => {const { token } = req.paramsconst filename = req.query.nameconst contentUrl = `https://${ZENDESK_SUBDOMAIN}.zendesk.com/attachments/token/${token}/?name=${filename}`try {const response = await axios.get(contentUrl, {headers: {Authorization: `Bearer ${ZENDESK_ACCESS_TOKEN}`},maxRedirects: 0,validateStatus: status => status === 302})res.redirect(response.headers['location'])} catch (error) {// Handle error based on your application's requirementsres.status(500).send('Unable to retrieve attachment')}})
Python
@app.route('/attachments/token/<token>/')def proxy_attachment(token):filename = request.args.get('name')content_url = f"https://{ZENDESK_SUBDOMAIN}.zendesk.com/attachments/token/{token}/?name={filename}"response = requests.get(content_url,headers=HEADERS,allow_redirects=False)if response.status_code != 302:# Handle error based on your application's requirementsreturn 'Unable to retrieve attachment', 500return redirect(response.headers['Location'])
Note: The error handling shown above is minimal. Adjust the error responses based on your application's requirements.