Receivng 500 error from all endpoints when using php curl

Hello,

I am using the php curl example here to create an outbound email : fresh-samples/PHP/send_outbound_email_with_multiple_cc_emails_and_attachments.php at master · freshworks/fresh-samples · GitHub

As we will often need to add multiple attachments when creating the outbound email, we are using the example above that uses the content type multipart/form-data

Our sample code for the above endpoint is shown below. You will need to add your domain, email_config_id and api key to test.

The 500 error being returned is shown after.

The curl get_info is shown last

I must mention at this point that the 500 error is being returned no matter what endpoint we use. We have tried 4 endpoints so far using php curl.

Please assist if you can. Thanks.

OUR PHP CURL

<?php 

$url = "https://domain.freshdesk.com/api/v2/tickets/outbound_email"; //replace with your domain
$email_config_id = "" ; //replace with your email_config_id


## Code starts:
$eol = "\r\n";
$mime_boundary = md5(time());
$data .= '--' . $mime_boundary . $eol;

$data .= 'Content-Disposition: form-data; name="email"' . $eol . $eol;
$data .= "test4567@example.com" . $eol;
$data .= '--' . $mime_boundary . $eol;

$data .= 'Content-Disposition: form-data; name="subject"' . $eol . $eol;
$data .= "Testing outbound email" . $eol;
$data .= '--' . $mime_boundary . $eol;

$data .= 'Content-Disposition: form-data; name="priority"' . $eol . $eol;
$data .= "2" . $eol;
$data .= '--' . $mime_boundary . $eol;


$data .= 'Content-Disposition: form-data; name="status"' . $eol . $eol;
$data .= "2" . $eol;
$data .= '--' . $mime_boundary . $eol;

$data .= 'Content-Disposition: form-data; name="description"' . $eol . $eol;
$data .= "test" . $eol;
$data .= '--' . $mime_boundary . $eol;

$data .= 'Content-Disposition: form-data; name="email_config_id"' . $eol . $eol;
$data .= $email_config_id . $eol;
$data .= '--' . $mime_boundary . $eol;

$header[] = "Content-type: multipart/form-data; boundary=" . $mime_boundary;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS,$data);
curl_setopt($ch, CURLOPT_USERPWD, "APIKEY:X" ); //replace APIKEY with your API key
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec($ch);
$info = curl_getinfo($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($server_output, 0, $header_size);
$response = substr($server_output, $header_size);
if($info['http_code'] == 201) {
  echo "Ticket created successfully, the response is given below \n";
  echo "Response Headers are \n";
  echo $headers."\n";
  echo "Response Body \n";
  echo "$response \n";
} else {
  if($info['http_code'] != 201) {
    echo "Error, Please check the end point \n";
  } else {
    echo "Error, HTTP Status Code : " . $info['http_code'] . "\n";
    echo "Headers are ".$headers;
    echo "Response are ".$response;
  }
}
curl_close($ch);
?>

ERROR RETURNED

Error, HTTP Status Code : 500 Headers are HTTP/2 500 date: Wed, 25 Sep 2024 17:15:19 GMT content-type: application/json status: 500 Internal Server Error x-request-id: 32c59ca5-6e0a-4d2e-8967-cdb75fa9631c x-freshdesk-api-version: latest=v2; requested=v2 content-security-policy: default-src 'self'; connect-src 'self' *.freshconnect.io/ *.freshsales.io/ *.freshworks.com/ *.freshdesk.com/ *.freshworksapi.com/ *.freshdeskusercontent.com/ *.freshdeskusercontent-euc.com/ *.freshdeskusercontent-in.com/ *.freshdeskusercontent-aus.com/ *.fconstage.io/ analytics.inlinemanual.com/__profile analytics.inlinemanual.com/__ptm backend.getbeamer.com/ heapanalytics.com/ d3h0owdjgzys62.cloudfront.net/ d2uy6ubiilaqku.cloudfront.net/assets/ dcdu85ocrj5q6.cloudfront.net/ dtdafz6i4gvv1.cloudfront.net/ d3r4aewxkdubw4.cloudfront.net/ d2lz1e868xzctj.cloudfront.net/ rum.haystack.es/freshdesk/analytics fonts.googleapis.com/ fonts.gstatic.com/ sentry.io/api/ wss://*.freshworksapi.com/ wss://*.freshdesk.com/ fg8vvsvnieiv3ej16jby.litix.io/ distillery.wistia.com/ pipedream.wistia.com/ freshworks.asknice.ly/ embedwistia-a.akamaihd.net/ embed-fastly.wistia.com/ maps.googleapis.com/ graph.microsoft.com/v1.0/ freshcaller-attachments.s3.amazonaws.com/production/ euc-freshcaller-attachments.s3.eu-central-1.amazonaws.com/production/ mec-freshcaller-attachments.s3.me-central-1.amazonaws.com/production/ au-freshcaller-attachments.s3-ap-southeast-2.amazonaws.com/production/ in-freshcaller-attachments.s3.ap-south-1.amazonaws.com/production/ pubsub.rtschannel.com/ api.fdcollab.com/ wss://pubsub.rtschannel.com/ cloudflareinsights.com/ data: blob: api.appcues.net/ wss://api.appcues.net/ fast.appcues.com/ cdn.jsdelivr.net/npm/@freshworks/crayons-icon@next/dist/ translate.googleapis.com/translate_a/t translate.googleapis.com/element/log fast.wistia.net/ fast.wistia.com/ embed-cloudfront.wistia.com/deliveries/ app.inlinemanual.com/ client-api.auryc.com/ *.surveyserv.com *.freshsurvey.com *.freddybot.com; font-src 'self' *.freshdesk.com/ fonts.gstatic.com/ fonts.googleapis.com/ cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/fonts/ fast.wistia.net/ fast.wistia.com/ *.freddybot.com cdn.inlinemanual.com/inm/author/ data:; frame-src 'self' https:; img-src 'self' https: data: blob:; media-src 'self' https: blob:; object-src 'none'; script-src 'self' *.freshworksapi.com/ *.freshworks.com/ *.myfreshworks.com/ *.freshdesk.com/ *.freshchat.com/ *.freshcaller.com/ *.freshconnect.io/ *.freshcloud.io/ *.fconstage.io/ wchat.freshchat.com/js/ wchat.freshchat.com/widget/js/ assets.calendly.com/assets/external/widget.js d3h0owdjgzys62.cloudfront.net/ d2uy6ubiilaqku.cloudfront.net/ dtdafz6i4gvv1.cloudfront.net/ dcdu85ocrj5q6.cloudfront.net/ d3r4aewxkdubw4.cloudfront.net/ app.getbeamer.com/js/beamer-embed.js analytics.inlinemanual.com/ cdn.inlinemanual.com/embed/ cdn.heapanalytics.com/ cdnjs.cloudflare.com/ ajax.cloudflare.com/ static.cloudflareinsights.com/ js.chargebee.com/v1/chargebee.js js.braintreegateway.com/v1/braintree.js static.freshdev.io/ fast.wistia.net/ fast.wistia.com/ static.getbeamer.com/ calendly.com/ unpkg.com/@webcomponents/webcomponentsjs@2.4.3/custom-elements-es5-adapter.js unpkg.com/@webcomponents/webcomponentsjs@2.4.3/webcomponents-loader.js js-agent.newrelic.com/ www.googletagmanager.com/gtag/js static.asknice.ly/dist/standalone/asknicely-in-app-conversation.js www.dropbox.com/static/api/2/dropins.js js.live.net/v7.2/OneDrive.js apis.google.com/ asknice.ly bam.nr-data.net/ www.google-analytics.com/analytics.js maps.googleapis.com/ unpkg.com/@freshworks/crayons@v3/dist/crayons/crayons.esm.js unpkg.com/@freshworks/crayons@v3/dist/crayons/crayons.js s3.amazonaws.com/freshcaller-widget-loader/ in-freshcaller-widget-loader.s3.ap-south-1.amazonaws.com/ s3.eu-central-1.amazonaws.com/euc-freshcaller-widget-loader/ mec-freshcaller-widget-loader.s3.me-central-1.amazonaws.com/ au-freshcaller-widget-loader.s3-ap-southeast-2.amazonaws.com/ www.dropbox.com/static/api/1/dropbox.js fast.appcues.com/ translate.google.com/translate_a/element.js translate.googleapis.com/_/translate_http/_/js/ translate-pa.googleapis.com/v1/supportedLanguages cdn.surveyserv.com/widget.min.js cdn.freshdev.io/assets/marketplace-heap.js cdn.freshcloud.io/assets/marketplace-heap.js cdn.inlinemanual.com/inm/author/ app.inlinemanual.com/ *.surveyserv.com *.freshsurvey.com www.google.com/recaptcha/ www.gstatic.com/recaptcha/ *.freddybot.com d3el5jsqgryo0a.cloudfront.net accounts.google.com/ 'unsafe-inline' 'unsafe-eval'; style-src 'self' *.freshworks.com *.myfreshworks.com/ *.freshchat.com/ d3h0owdjgzys62.cloudfront.net/ dcdu85ocrj5q6.cloudfront.net/ dtdafz6i4gvv1.cloudfront.net/ d3r4aewxkdubw4.cloudfront.net/ d2uy6ubiilaqku.cloudfront.net/ fonts.googleapis.com/ app.getbeamer.com/styles/beamer-embed.css *.freshdesk.com/ calendly.com/ unpkg.com/@webcomponents/webcomponentsjs@2.4.3/custom-elements-es5-adapter.js unpkg.com/@webcomponents/webcomponentsjs@2.4.3/webcomponents-loader.js static.asknice.ly/dist/standalone/asknicely-in-app-conversation.css fast.appcues.com/ asknice.ly *.surveyserv.com *.freshsurvey.com *.freddybot.com cdn.inlinemanual.com/inm/author/ 'unsafe-inline'; worker-src 'self' blob: x-xss-protection: 1; mode=block x-content-type-options: nosniff x-fw-ratelimiting-managed: true x-ratelimit-total: 50 x-ratelimit-remaining: 48 x-ratelimit-used-currentrequest: 1 x-envoy-upstream-service-time: 40 x-trace-id: 00-d70606c0a6f4846017d29071b0650e4e-8cdc414e5859a8d6-00 nel: { "report_to": "nel-endpoint-freshdesk", "max_age": 2592000, "include_subdomains": true} report-to: { "group": "nel-endpoint-freshdesk", "max_age": 2592000, "include_subdomains": true, "endpoints": [{"url": "https://edge-admin.eu-central-1.freshedge.net/nelreports/freshdesk"}]} server: fwe Response are {"code":"internal_error","message":"We're sorry, but something went wrong."}

CURL INFO

{
  "url": "https://**domain**.freshdesk.com/api/v2/tickets/outbound_email",
  "content_type": "application/json",
  "http_code": 500,
  "header_size": 5768,
  "request_size": 1050,
  "filetime": -1,
  "ssl_verify_result": 0,
  "redirect_count": 0,
  "total_time": 0.120477,
  "namelookup_time": 0.02907,
  "connect_time": 0.043152,
  "pretransfer_time": 0.060019,
  "size_upload": 805,
  "size_download": 76,
  "speed_download": 630,
  "speed_upload": 6681,
  "download_content_length": -1,
  "upload_content_length": 805,
  "starttransfer_time": 0.120449,
  "redirect_time": 0,
  "redirect_url": "",
  "primary_ip": "18.195.84.42",
  "certinfo": [],
  "primary_port": 443,
  "local_ip": "35.214.105.201",
  "local_port": 35786,
  "http_version": 3,
  "protocol": 2,
  "ssl_verifyresult": 0,
  "scheme": "HTTPS",
  "appconnect_time_us": 59889,
  "connect_time_us": 43152,
  "namelookup_time_us": 29070,
  "pretransfer_time_us": 60019,
  "redirect_time_us": 0,
  "starttransfer_time_us": 120449,
  "total_time_us": 120477
}

This has been resolved by the Freshdesk team. For anyone with a similar issue who comes across this in future, the github samples seem to need updating.

You will need to add an authorization header and remove curlopt_userpwd as shown below. The endpoints do not seem to work with curlopt_userpwd as shown in the github samples.

Secondly, if using Content-Type: multipart/form-data, you must have the attachment field in the post data, else it returns a 500 error. So if the ticket/outbound email wont have an attachment use the application/json content type & use the sample code on github for that content type (with the authorization header added & curlopt_userpwd remove as earlier mentioned)

<?php 

$url = "https://domain.freshdesk.com/api/v2/tickets/outbound_email"; //replace with your domain
$email_config_id = "" ; //replace with your email_config_id
$apiKey = ""; //replace with your api key
$password = "x",

## Code starts:
$eol = "\r\n";
$mime_boundary = md5(time());
$data .= '--' . $mime_boundary . $eol;

$data .= 'Content-Disposition: form-data; name="email"' . $eol . $eol;
$data .= "test4567@example.com" . $eol;
$data .= '--' . $mime_boundary . $eol;

$data .= 'Content-Disposition: form-data; name="subject"' . $eol . $eol;
$data .= "Testing outbound email" . $eol;
$data .= '--' . $mime_boundary . $eol;

$data .= 'Content-Disposition: form-data; name="priority"' . $eol . $eol;
$data .= "2" . $eol;
$data .= '--' . $mime_boundary . $eol;


$data .= 'Content-Disposition: form-data; name="status"' . $eol . $eol;
$data .= "2" . $eol;
$data .= '--' . $mime_boundary . $eol;

$data .= 'Content-Disposition: form-data; name="description"' . $eol . $eol;
$data .= "test" . $eol;
$data .= '--' . $mime_boundary . $eol;

$data .= 'Content-Disposition: form-data; name="email_config_id"' . $eol . $eol;
$data .= $email_config_id . $eol;
$data .= '--' . $mime_boundary . $eol;

$headers = array(
    "Authorization: Basic " . base64_encode("$apiKey:$password"),
    "Content-Type: multipart/form-data; boundary=" . $mime_boundary
);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS,$data);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec($ch);
$info = curl_getinfo($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($server_output, 0, $header_size);
$response = substr($server_output, $header_size);
if($info['http_code'] == 201) {
  echo "Ticket created successfully, the response is given below \n";
  echo "Response Headers are \n";
  echo $headers."\n";
  echo "Response Body \n";
  echo "$response \n";
} else {
  if($info['http_code'] == 404) {
    echo "Error, Please check the end point \n";
  } else {
    echo "Error, HTTP Status Code : " . $info['http_code'] . "\n";
    echo "Headers are ".$headers;
    echo "Response are ".$response;
  }
}
curl_close($ch);
?>