I'm trying to communicate with the eBay Trading API. I'm using PHP and sending the request using CURL. I'm getting the following error:

Code:
nested exception is: org.xml.sax.SAXParseException: The element type "soapenv:Body" must be terminated by the matching end-tag "</soapenv:Body>"
I'm confused because I didn't think I was doing anything with the SOAP envelope myself. This is the XML I'm sending:

Code:
<AddItemRequest xmlns="urn:ebay:apis:eBLBaseComponents">
	<ErrorLanguage>en_GB</ErrorLanguage>
	<WarningLevel>High</WarningLevel>
	<Item>
		<Title>Test Product Title</Title>
		<Description>This is a sample description.</Description>
		<PrimaryCategory>
			<CategoryID>377</CategoryID>
		</PrimaryCategory>
		<StartPrice>1.00</StartPrice>
		<ConditionID>3000</ConditionID>
		<CategoryMappingAllowed>true</CategoryMappingAllowed>
		<Country>UK</Country>
		<Currency>GBP</Currency>
		<DispatchTimeMax>3</DispatchTimeMax>
		<ListingDuration>GTC</ListingDuration>
		<ListingType>FixedPriceItem</ListingType>
		<PaymentMethods>PayPal</PaymentMethods>
		<PayPalEmailAddress>info@example.com</PayPalEmailAddress>
		<PictureDetails>
			<PictureURL>http://www.example.com/images/image.jpg</PictureURL>
		</PictureDetails>
		<PostalCode>12345</PostalCode>
		<Quantity>1</Quantity>
		<ReturnPolicy>
			<ReturnsAcceptedOption>ReturnsAccepted</ReturnsAcceptedOption>
			<RefundOption>MoneyBack</RefundOption>
			<ReturnsWithinOption>Days_30</ReturnsWithinOption>
			<Description>This is a sample description.</Description>
			<ShippingCostPaidByOption>Buyer</ShippingCostPaidByOption>
		</ReturnPolicy>
		<ShippingDetails>
			<ShippingType>Flat</ShippingType>
			<ShippingServiceOptions>
				<ShippingServicePriority>1</ShippingServicePriority>
				<ShippingService>UPS Standard</ShippingService>
				<ShippingServiceCost>0.00</ShippingServiceCost>
			</ShippingServiceOptions>
		</ShippingDetails>
		<Site>UK</Site>
		<UUID>7A851461-AF91-5CD0-F244-BF88CCE76C6C</UUID>
	</Item>
	<RequesterCredentials>
		<eBayAuthToken>blahblah</eBayAuthToken>
	</RequesterCredentials>
	<WarningLevel>High</WarningLevel>
</AddItemRequest>
These are the options that are set:

Code:
curl_setopt($connection, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($connection, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($connection, CURLOPT_HTTPHEADER, $headers);
curl_setopt($connection, CURLOPT_POST, true);
curl_setopt($connection, CURLOPT_POSTFIELDS, $requestBody);
curl_setopt($connection, CURLOPT_RETURNTRANSFER, true);
And the headers:

Code:
$headers = array (
	'X-EBAY-API-COMPATIBILITY-LEVEL: ' . $this -> compatLevel,
	'X-EBAY-API-DEV-NAME: ' . $this -> devID,
	'X-EBAY-API-APP-NAME: ' . $this -> appID,
	'X-EBAY-API-CERT-NAME: ' . $this -> certID,
	'X-EBAY-API-CALL-NAME: ' . $this -> callName,
	'X-EBAY-API-SITEID: ' . $this -> siteID,
	'Content-Type: ' . 'text/xml',
	'Content-Length: ' . $this -> contentLength
	);
Does anyone have any ideas why it appears that the request being sent is malformed? I've Googled high and low but I'm still scratching my head.