Follow

Code related issues with API

Access denied

If you are getting "Access denied" error from Visma Severa API, it often is because of some information is lacking in your customer's Visma Severa's settings. Check the following together with your customer:

  • Is API addon active for the organization in Visma Severa's Upgrades section? API needs to be active in order to use it.
  • Which user is the API user of the organization? Usually it is recommended to have a special API user. If integration is done so that there are many API keys in use, check which one is giving you the error, and look at the Personal details of that user in Visma Severa with your customer.
    • Does this user have API access right "Yes" in Personal details page, Access rights section? Without API access right it is not possible to use API.
    • Does this user have API enabled in Personal details page, API section?
    • Does the API key of the user match with the API key which is used in the integration?
    • Does the user have the widest access rights possible? If user's access rights aren't wide, it is likely that the user won't be able to get needed data from Visma Severa's API.

Buffer size

.Net WCF default buffer size may prohibit large amounts of data to being transferred to/from WebService API.

  • MSDN article about .Net 4 WCF configuration <bindings>
  • Pay attention to:
    • maxBufferSize
    • maxReceivedMessageSize
  • Both buffers are 64 KiB as default. That is way too small if transferring a lot of data.
    • Recommend using 67108864 bytes (64 MiB) instead.

Example app.config file:

<binding name="Severa.API.IAccount" closeTimeout="00:01:00" openTimeout="00:01:00"
    receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
    bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
    maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
    useDefaultWebProxy="true">
    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
    <security mode="Transport">
        <transport clientCredentialType="None" proxyCredentialType="None"
            realm="" />
        <message clientCredentialType="UserName" algorithmSuite="Default" />
    </security>
</binding>

 

If your code does not use app.config auto-generated binding, in your binding code you can do something like this (C# example):

System.ServiceModel.EndpointAddress endpoint = new System.ServiceModel.EndpointAddress(new Uri("https://sync.severa.com/webservice/S3/API.svc"));
System.ServiceModel.BasicHttpBinding binding = new System.ServiceModel.BasicHttpBinding(System.ServiceModel.BasicHttpSecurityMode.Transport);
binding.Name = "Severa";
binding.Namespace = "http://soap.severa.com/";
binding.MaxBufferSize = 67108864;
binding.MaxReceivedMessageSize = 67108864;

 

Array length

The following exception occurs when for example downloading invoice PDF files from Visma Severa through API, and file bytes exceed the current limit:

  • "The maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element."
  • In this case, increase the maxArrayLength value in app.config file for the binding in question.
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
        maxBytesPerRead="4096" maxNameTableCharCount="16384" />

Max items in object graph

The MaxItemsInObjectGraph property specifies the maximum number of objects that the serializer serializes or deserializes in a single ReadObject method call.

  • Recommendation to set 10000000 for the client.
  • Read more about MaxItemsInObjectGraph from MSDN article.

MaxItemsInObjectGraph can be set in app.config, or by code to each endpoint:

private void SetBehaviour( System.ServiceModel.Description.ServiceEndpoint endpoint )
    {
        foreach( var operationDescription in endpoint.Contract.Operations )
            {
                var behaviour = operationDescription.Behaviors.Find();
                if( behaviour != null )
                    {
                        behaviour.MaxItemsInObjectGraph = int.MaxValue;
                    }
            }
    }

 

Timeout

To prevent timeout from happening when making API calls that return a lot of data, set the timeout properties of bindings in your client. By default timeout is set to 1 minute.

  • Notice that in many API entities there are several entities gathered together. For example when getting an invoice from API, actually invoice, invoice configuration, invoice details and invoice rows are returned. So when client does one API call, Visma Severa is internally making several calls to get the required data.
  • In many API interfaces there are "GetChangedSince" methods, which are designed to return data that has been inserted or changed after certain date & time, which is given as parameter. These methods should be used when getting data from Visma Severa through API.
  • Read more about Timeout value configuration from MSDN article.

 

API downtime

When there is downtime in API, HTTP error 503 will occur.

The error will look like this in browser when accessing API WSDL

API downtime wsdl.png

When integrating, the exception, which comes, is:

API_downtime_message_in_popup.png

The stack is the following, see that in InnerException there is (503) Server Unavailable:

System.ServiceModel.ServerTooBusyException was caught
  Message=The HTTP service located at https://sync-test.severa.com/webservice/S3/API.svc is too busy.
  Source=mscorlib
  StackTrace:
    Server stack trace:
       at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)
       at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
       at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
       at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
       at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
       at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
       at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
    Exception rethrown at [0]:
       at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
       at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
       at ApiTest.SeveraAPI.IAccount.GetAccountByNumber(Int64 accountNumber)
       at ApiTest.SeveraAPI.AccountClient.GetAccountByNumber(Int64 accountNumber) in ...\Reference.vb:line 13557
       at ApiTest.account.GetAccountByNumber(String apiKey, Int32 accountNumber) in ...:line 246
  InnerException: System.Net.WebException
       Message=The remote server returned an error: (503) Server Unavailable.
       Source=System
       StackTrace:
            at System.Net.HttpWebRequest.GetResponse()
            at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)

 In code, the exception looks like this:

 exception_API_downtime.png

And exception details look like this:

exception_detail_API_downtime.png

 

Was this article helpful?
0 out of 0 found this helpful
Have more questions? Submit a request

0 Comments

Powered by Zendesk