shacklrobert
shacklrobert

Reputation: 79

Xero OAuth 2.0 API - c# dotnet core - unauthorised when upload attachment to invoice - other requests fine

I have a dotnet core web app that uses the xero OAUTH2 invoice just fine to add invoices and query data. But when I try to upload an attachment I get a 401 unauthorised response. Here's the code with the issue

if (timeRecordAttachment != null)
{
    try
    {
        string fileName = $"TimeRecord-{exportTotal.ExportCustomer.Code}-H-{exportTotal.ExportHeader.Id}-{exportTotal.ExportHeader.Year:0000}-{exportTotal.ExportHeader.Month:00}.txt";
        await _accountingApi.CreateInvoiceAttachmentByFileNameAsync(xeroToken.AccessToken, _configuration["Xero:TenantId"], (Guid)exportTotal.XeroInvoiceId, fileName, timeRecordAttachment, true).ConfigureAwait(false);
    }
    catch (ApiException ex)
    {
         _logger.LogWarning($"API exception code {ex.ErrorCode} and Message {ex.Message} was thrown when uploading pdf time record - invoice has been created");
    }
    catch
    {
        throw;
    }
}
logger.LogInformation($"Invoice {generatedInvoice.InvoiceID} created with number {generatedInvoice.InvoiceNumber} for total Id {id}");

The error is:

API exception code 401 and Message Xero API error calling CreateInvoiceAttachmentByFileName: {"Type":null,"Title":"Unauthorized","Status":401,"Detail":"AuthorizationUnsuccessful","Instance":"4dbcd6ca-d260-417c-a8d3-4cde373bfdd9","Extensions":{}} was thrown when uploading pdf time record - invoice has been created

Are some special permissions required to upload invoices? I am using a demo organization right now for testing, could that be it?

Invoice creation works just fine a few lines earlier:

Invoice generatedInvoice = new Invoice();
try
{
    var response = await _accountingApi.CreateInvoicesAsyncWithHttpInfo(xeroToken.AccessToken, _configuration["Xero:TenantId"], invoices).ConfigureAwait(false);
    generatedInvoice = response.Data._Invoices.FirstOrDefault();
}

For those reading this with a similar issue, I edited the scopes to include accounting.attachments

"Xero": {
    "Scopes": "openid profile email accounting.transactions accounting.contacts accounting.settings offline_access accounting.attachments"
  },

Upvotes: 1

Views: 724

Answers (1)

MJMortimer
MJMortimer

Reputation: 865

The most common reasons for 401 responses via OAuth2.0 are expired tokens, or incorrect scopes.

If you're able to use your access token for some endpoints but not others it's probably not an expired token issue.

My guess is that when you authorised the connection, you didn't ask for the accounting.attachments scope and so your user hasn't allowed you to manage their attachments on their behalf.

I'm a developer for Xero working on our APIs and so if you don't think this is the reason, you could edit your question to include the some-guid-here Instance property in your response message and I can correlate with logs on our side

Upvotes: 2

Related Questions