Introduktion

Vi tillhandahåller ett API för maskinella uppdateringar av servicedata. 
Detta API lämpar sig för organisationer som har IT-avdelningar/utvecklare, då det krävs att dataleverantörer utvecklar egna klienter för att jobba mot vårt API. 

Med ServiceApi får du programmatiskt tillgång till Tillväxtverkets tjänster för att uppdatera servicedata.
Nedanstående video beskriver vår datamodell och centrala begrepp:

 

ServiceApi är ett REST-baserat API där data överförs som JSON.
För att använda ServiceApi krävs ett giltigt användarnamn och lösenord.

Tillväxtverket tillhandahåller en testinstans av ServiceApi som med fördel används vid utveckling och test.
Innehållet i testinstansens databas återställs varje natt.

Testinstansen har även ett grafiskt gränssnitt som nås genom samma adress och användaruppgifter.

Testserver
Url

https://kontantanalys.tillvaxtverket.se/test/

Användarnamntestbanken
LösenordSommar&sol2020

Uppdateringsstrategier

Det finns flera strategier för att uppdatera data via vårt API, bland annat inkrementell och full uppdatering.
Båda strategierna kräver att leverantörens data matchas mot Tillväxtverkets servicedata.
ServiceApi tillhandahåller inga mekanismer för att matcha data, det ansvarar respektive leverantör för.
En matchning kan göras genom att hämta ut alla serviceplatser och sedan jämföra exempelvis dess adresser och koordinater med leverantörens interna register. 

I Tillväxtverkets databas finns idag ca 17 000 serviceplatser och många av utförarna är samma år från år för de olika servicetyperna. Sannolikheten att det redan finns en befintlig serviceplats i databasen att koppla på en service till är därför stor. Trots detta kan en matchning mellan exempelvis besöksadress och postort ge relativt få träffar eftersom adresserna kan vara skrivna på olika sätt i de olika matchningsregistren.

Försök i möjligaste mån matcha mot en befintlig serviceplats innan ni ger er på att skapa helt nya serviceplatser. Tänk på att det kan finnas andra attribut i utförarinformationen som också går att matcha på än besöksadress och koordinat. Exempelvis kan även serviceplatsens namn vara vägledande för matchningsmetoden.     

Inkrementell

Hämta via API en kollektion med all service och dess serviceplatser som leverantören ansvarar för.
Uppdatera de som har ändrats.
Radera de som har försvunnit.
Skapa de som har tillkommit.
När en ny service skapas, kontrollera ifall det finns en serviceplats på aktuell adress och använd den, annars skapa en ny serviceplats.
Endast serviceplatser som saknar relationer till service får raderas.
Upptäcks fel på befintliga serviceplatser, rapporteras dessa med ett ändringsförslag.

Full uppdatering

Vid en full uppdatering, då raderas först all service som leverantören ansvarar för, sedan skapas all service igen och binds till befintliga serviceplatser.
Fördelen med en full uppdatering är att borttag, nya och uppdateringar inte behöver hanteras separat, däremot måste all service som skapas matchas mot befintliga serviceplatser (där det är möjligt).

Autentisering

För att använda API'et krävs ett giltigt konto som utfärdas av Tillväxtverket.

Autentiseringen baseras på OAuth 2.0 Authentication.

Ett giltigt token erhålls efter en accepterad inloggning, därefter används denna token (bakas in i HTTP headern Authorization) i alla anrop mot API'et. 

Logga in med en användare

Request

POST /Token HTTP/1.1
Accept: application/json
Content-Type: application/x-www-form-urlencoded; charset=UTF-8


grant_type=password&username=testbanken&password=Sommar&sol2020

Response 200 OK

HTTP/1.1 200 OK
Content-Type: application/json

{
  "access_token": "imSXTs2aiadQhIXffziFCO3rF...",
  "token_type": "bearer",
  "expires_in":1209599,
  "userName": "testbanken",
  ".issued": "Wed, 01 Oct 2017 01:22:33 GMT",
  ".expires": "Wed, 15 Oct 2017 01:22:33 GMT"
}

Användning av token

Vid anrop till API'et sätts HTTP headern Authorization till Bearer följt av ett mellanslag och sedan värdet av token (access_token som erhölls vid inloggningen ovan).

Request

GET /api/providers/7000 HTTP/1.1
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

Provider (Serviceplats) 

Beskrivning av attribut

NamnTypKrav vid update/createBeskrivning

id

intfrivillig, går inte att ändraServiceplatsens id, genereras av servern.

name

stringobligatoriskNamnet på serviceplatsen (ex. ICA Kvantum Landskrona, Swedbank AB Åre, Statoil Frösön).

code

stringfrivillig, går inte att ändraIntern unik kod för serviceplatsen, genereras av servern och används bland annat för att förenkla återkoppling vid uppdatering.

visitingAddress

stringobligatoriskServiceplatsens besöksadress.

postalCode

stringobligatoriskServiceplatsens postnummer.

postTown

stringobligatoriskServiceplatsens postort.

x

floatobligatoriskServiceplatsens x-koordinat i SWEREF99 TM (EPSG:3006)
yfloatobligatoriskServiceplatsens y-koordinat i SWEREF99 TM (EPSG:3006)

services

arrayutelämnas

En lista över service som serviceplatsen tillhandahåller (en serviceplats kan tillhandahålla flera service av samma typ och form under förutsättning att servicen har olika huvudmän).

Default tom, används bara då 'embedservices' sätts till true i anropet FindAll.

propertiesdictionaryfrivillig

En dictionary med nycklar och värden för att lagra egendefinierad data till serviceplatsen.

Kan fritt användas för att t.ex. spara metadata som externa id'n (för att förenkla koppling/matchning mot externt data) eller geokodningens källa.

GetProvider (hämta en serviceplats)

Request

GET /api/providers/7000 HTTP/1.1
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

Response 200 OK

HTTP/1.1 200 OK
Content-Type: application/json

{
  "data": {
    "type": "provider",
    "id": 7000,
    "attributes": {
	  "id": 7000,
 	  "name": "INGO Örebro, Adolfsbergsvägen",
      "code": "INGO-0079",
      "visitingAddress": "Adolfsbergsvägen 4",
	  "postalCode": "702 27",
 	  "postTown": "ÖREBRO",
	  "x": 509886.4,
  	  "y": 6568855.5,
	  "services": [],
	  "properties": {}
	}
  }
}

Response 404 Not Found

HTTP/1.1 404 Not Found
Content-Type: application/json

{
  "errors": [{
    "detail": "Requested provider not found"
  }]
}


GetServicesForProvider (hämta den service som tillhandahålls av serviceplatsen)

Request

GET /api/providers/7000/services HTTP/1.1
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

Response 200 OK

HTTP/1.1 200 OK
Content-Type: application/json

{
  "type": "service",
  "id": 30000,
  "data": [{
	"attributes": {
	  "id": 30000,
  	  "providerId": 7000,
	  "servicePrincipalId": 20,
	  "serviceTypeId": 2,
	  "forms": ["Bankkassa med kontanter","Bankkassa mot bankkonto/kort"],
	  "properties": null,
	  "active": true,
	  "year": 0
	}, {
	"attributes": {
	  "id": 30001,
  	  "providerId": 7000,
	  "servicePrincipalId": 20,
	  "serviceTypeId": 1,
	  "forms": ["Uttagsautomat"],
	  "properties": null,
	  "active": true,
	  "year": 0
	}]
  }
}

Response 404 Not Found

HTTP/1.1 404 Not Found
Content-Type: application/json

{
  "errors": [{
    "detail": "Requested provider not found"
  }]
}

GetServicesForProviderByYear (hämta den service som tillhandahålls av serviceplatsen för ett specifikt år)

Request

GET /api/providers/7000/services/2016 HTTP/1.1
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

Response 200 OK

HTTP/1.1 200 OK
Content-Type: application/json

{
  "type": "service",
  "id": 30000,
  "data": [{
	"attributes": {
	  "id": 30000,
  	  "providerId": 7000,
	  "servicePrincipalId": 20,
	  "serviceTypeId": 2,
	  "forms": ["Bankkassa med kontanter","Bankkassa mot bankkonto/kort"],
	  "properties": null,
	  "active": true,
	  "year": 2016
	}, {
	"attributes": {
	  "id": 30001,
  	  "providerId": 7000,
	  "servicePrincipalId": 20,
	  "serviceTypeId": 1,
	  "forms": ["Uttagsautomat"],
	  "properties": null,
	  "active": true,
      "year": 2016
	}]
  }
}

Response 404 Not Found

HTTP/1.1 404 Not Found
Content-Type: application/json

{
  "errors": [{
    "detail": "Requested provider not found"
  }]
}

FindAllProviders (hämta en lista med serviceplatser, utifrån sökkriterier) 

ParameterTypKravBeskrivning
querystring

frivillig

fulltextsökning
servicetypestring

frivillig

Hämta bara serviceplatser som tillhandahåller service av en viss typ (t.ex. Kontantuttag eller Dagligvaruförsäljning)
limitint

frivillig

Anger hur många serviceplatser som ska hämtas åt gången
startint

frivillig

Anger hur många serviceplatser som ska hoppas över vid paging
embedservicesbool

frivillig

Anger om den service som serviceplatsen tillhandahåller ska inkluderas in i svaret.


Request

GET /api/providers HTTP/1.1
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

Response 200 OK

HTTP/1.1 200 OK
Content-Type: application/json

{
  "data": [{
    "type": "provider",
    "id": 7000,
    "attributes": {
	  "id": 7000,
 	  "name": "INGO Örebro, Adolfsbergsvägen",
      "code": "INGO-0079",
      "visitingAddress": "Adolfsbergsvägen 4",
	  "postalCode": "702 27",
 	  "postTown": "ÖREBRO",
	  "x": 509886.4,
  	  "y": 6568855.5,
	  "services": [],
	  "properties": {}
	}
  }, 
  // ...
  {
    "id": 7001,
    "type": "provider",
    "attributes": {
      "id": 7001,
      "name": "INGO Örebro, Bettorpsgatan",
   	  "code": "INGO-0080",
	  "visitingAddress": "Bettorpsgatan 24",
	  "postalCode": "703 69",
	  "postTown": "ÖREBRO",
	  "x": 513141.5,
	  "y": 6574119.3,
	  "services": [],
	  "properties": {}
    }
  }]
}

FindProvidersByCoordinate (hämta en lista med serviceplatser inom en radie från en angiven koordinat)

Funktionen returnerar en lista med serviceplatser som är sorterad på avståndet från serviceplatsen till koordinaten (närmast först).

ParameterTypKravBeskrivning
xint

obligatorisk

X-koordinat i SWEREF 99
yint

obligatorisk

Y-koordinat i SWEREF 99
bufferint

obligatorisk

Sökradie i meter
limitint

frivillig

Anger hur många serviceplatser som ska hämtas åt gången

Request

GET /api/providers/coordinate?x=466588&y=6985694&buffer=1000 HTTP/1.1
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

Response 200 OK

HTTP/1.1 200 OK
Content-Type: application/json

{
  "data": [{
    "type": "provider",
    "id": 7000,
    "attributes": {
	  "id": 7000,
 	  "name": "INGO Örebro, Adolfsbergsvägen",
      "code": "INGO-0079",
      "visitingAddress": "Adolfsbergsvägen 4",
	  "postalCode": "702 27",
 	  "postTown": "ÖREBRO",
	  "x": 509886.4,
  	  "y": 6568855.5,
	  "services": [],
	  "properties": {}
	}
  }, 
  // ...
  {
    "id": 7001,
    "type": "provider",
    "attributes": {
      "id": 7001,
      "name": "INGO Örebro, Bettorpsgatan",
   	  "code": "INGO-0080",
	  "visitingAddress": "Bettorpsgatan 24",
	  "postalCode": "703 69",
	  "postTown": "ÖREBRO",
	  "x": 513141.5,
	  "y": 6574119.3,
	  "services": [],
	  "properties": {}
    }
  }]
}

FindProvidersByProperty (hämta en lista med serviceplatser filtrerat ett "nyckel/värde"-par i attributet properties)

ParameterTypKravBeskrivning
keystring

obligatorisk

Nyckeln i properties
valuestring

obligatorisk

Nyckelns värde
limitint

frivillig

Anger hur många serviceplatser som ska hämtas åt gången

Request

GET /api/providers/property/?key=externalId&value=123456 HTTP/1.1
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

Response 200 OK

HTTP/1.1 200 OK
Content-Type: application/json

{
  "data": [{
    "type": "provider",
    "id": 7000,
    "attributes": {
	  "id": 7000,
 	  "name": "INGO Örebro, Adolfsbergsvägen",
      "code": "INGO-0079",
      "visitingAddress": "Adolfsbergsvägen 4",
	  "postalCode": "702 27",
 	  "postTown": "ÖREBRO",
	  "x": 509886.4,
  	  "y": 6568855.5,
	  "services": [],
	  "properties": {
         "externalId": "123456"
	  }
	}
  }]
}

FindOwnProviders (hämta en lista med egna serviceplatser, dvs. serviceplatsen tillhandahåller service som aktuell användare äger) 

ParameterTypKravBeskrivning
servicetypestring

frivillig

Hämta bara serviceplatser som tillhanda håller service av en viss typ (t.ex. Kontantuttag eller Dagligvaruförsäljning)
limitint

frivillig

Anger hur många serviceplatser som ska hämtas åt gången
startint

frivillig

Anger hur många serviceplatser som ska hoppas över vid paging
embedservicesbool

frivillig

Anger om den service som serviceplatsen tillhandahåller ska inkluderas in i svaret.


Request

GET /api/providers/own HTTP/1.1
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

Response 200 OK

HTTP/1.1 200 OK
Content-Type: application/json

{
  "data": [{
    "type": "provider",
    "id": 7000,
    "attributes": {
	  "id": 7000,
 	  "name": "INGO Örebro, Adolfsbergsvägen",
      "code": "INGO-0079",
      "visitingAddress": "Adolfsbergsvägen 4",
	  "postalCode": "702 27",
 	  "postTown": "ÖREBRO",
	  "x": 509886.4,
  	  "y": 6568855.5,
	  "services": [],
	  "properties": {}
	}
  }, 
  // ...
  {
    "id": 7001,
    "type": "provider",
    "attributes": {
      "id": 7001,
      "name": "INGO Örebro, Bettorpsgatan",
   	  "code": "INGO-0080",
	  "visitingAddress": "Bettorpsgatan 24",
	  "postalCode": "703 69",
	  "postTown": "ÖREBRO",
	  "x": 513141.5,
	  "y": 6574119.3,
	  "services": [],
	  "properties": {}
    }
  }]
}


CreateProvider (skapa en ny serviceplats)

Request

POST /api/providers HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

{
  "data": {
    "type": "provider",
    "attributes": {
	  "name": "INGO Örebro, Adolfsbergsvägen",
      "visitingAddress": "Adolfsbergsvägen 4",
      "postalCode": "702 27",
      "postTown": "ÖREBRO",
      "x": 509886.4,
      "y": 6568855.5
    }
  }
}

Response 201 Created

HTTP/1.1 201 Created
Content-Type: application/json

{
  "data": {
    "type": "provider",
    "id": 7000,
    "attributes": {
	  "id": 7000,
 	  "name": "INGO Örebro, Adolfsbergsvägen",
      "code": "INGO-0079",
	  "x": 509886.4,
  	  "y": 6568855.5,
      "visitingAddress": "Adolfsbergsvägen 4",
	  "postalCode": "702 27",
 	  "postTown": "ÖREBRO",
	  "properties": {}
	}
  }
}

Response 409 Conflict

HTTP/1.1 409 Conflict
Content-Type: application/json

{
  "errors": [{
    "detail": "A provider with similar/equals attributes already exists",
    "source": "https://example.com/provider/6000"
  }]
}

UpdateProvider (uppdatera en befintlig serviceplats)

Request

PATCH /api/providers/7000 HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

{
  "data": {
    "type": "provider",
    "id": 7000,
    "attributes": {
 	  "name": "INGO Örebro, Adolfsbergsvägen",
      "code": "INGO-0079",
	  "x": 509886.4,
  	  "y": 6568855.5,
      "visitingAddress": "Adolfsbergsvägen 4",
	  "postalCode": "702 27",
 	  "postTown": "ÖREBRO",
	  "properties": {}
	}
  }
}

Response 200 OK

HTTP/1.1 200 OK
Content-Type: application/json

{
  "data": {
    "type": "provider",
    "id": 7000,
    "attributes": {
	  "id": 7000,
 	  "name": "INGO Örebro, Adolfsbergsvägen",
      "code": "INGO-0079",
	  "x": 509886.4,
  	  "y": 6568855.5,
      "visitingAddress": "Adolfsbergsvägen 4",
	  "postalCode": "702 27",
 	  "postTown": "ÖREBRO",
	  "properties": {}
	}
  }
}


Response 409 Conflict

HTTP/1.1 409 Conflict
Content-Type: application/json

{
  "errors": [{
    detail: "Invalid SWEREF99 coordinate"
  }]
}


Response 404 Not Found

HTTP/1.1 404 Not Found
Content-Type: application/json

{
  "errors": [{
    "detail": "Requested provider not found"
  }]
}


DeleteProvider (ta bort en befintlig serviceplats)

Request

DELETE /api/providers/7000 HTTP/1.1
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

Response 200 OK

HTTP/1.1 200 Ok
Content-Type: application/json

{}

Response 404 Not Found

HTTP/1.1 404 Not Found
Content-Type: application/json

{
  "errors": [{
    "detail": "Provider not found"
  }]
}

Response 409 Conflict

HTTP/1.1 409 Conflict
Content-Type: application/json

{
  "errors": [{
    detail: "The selected provider cannot be deleted since it is referenced by other services"
  }]
}

Service (tjänst) 

Beskrivning av attribut

NamnTypKrav vid update/createBeskrivning
idintGenererasServicens id, genereras av servern.
providerIdintObligatoriskId till serviceplatsen som tillhandahåller servicen, se Serviceplatser.
servicePrincipalIdintObligatoriskId för servicens huvudman, se Huvudman.
serviceTypeIdintObligatorisk

Id till typen av service som utförs, se Servicetyp.

propertiesdictionaryFrivillig

En dictionary med nycklar och värden som är knutna till specifik servicetyp.

ServicetypNyckelVärdeBeskrivning
KontantuttaglstboolUpphandlat tjänsteombud (LST)

ticketsRequiredbool

Inträdesbiljett krävs

BetalningsförmedlinglstboolUpphandlat tjänsteombud (LST)
DagskasseinsättninglstboolUpphandlat tjänsteombud (LST)
Dagligvaror fullsortimentmannedboolBemannad butik

revenueintOmsättning (tkr)

specialOperatingSupportboolSärskilt driftstöd
Dagligvaror ej fullsortimentmannedboolBemannad butik

revenueint Omsättning (tkr)
AllaexternalIdstring

Externt id som kan användas för att koppla service mot externt data

(för att förenkla uppdateringar).

formsarrayObligatorisk

Det sätt som servicen tillhandahålls. Form är knutet till servicetyp.

En service kan ha en eller flera former. Giltiga värden för form för respektive servicetyp beskrivs nedan.

Servicetypvärdebeskrivning
KontantuttagBankkassaÖver disk hos bankkontor
KontantuttagUttagsautomatAutomat för kontantuttag
KontantuttagÖver disk hos ombudOmbud som erbjuder kontantuttag till alla konsumenter eller där ett kreditinstitut eller annat företag har avtal som möjliggör kontantuttag för deras kunder
BetalningsförmedlingBankkassa med kontanterBankkontor där man kan betala räkningar med kontanter i kassan
BetalningsförmedlingBankkassa mot bankkonto/kortBankkontor där man kan betala räkningar via konto/kort i kassan
BetalningsförmedlingÖver disk hos ombudOmbud där man kan betala räkningar över disk
DagskasseinsättningÖver disk hos ombudOmbud som erbjuder dagskasseinsättning till alla företag eller där ett kreditinstitut eller annat företag har avtal som möjliggör dagskasseinsättning för deras kunder
DagskasseinsättningInsättningsautomatInsättningsautomat som möjliggör insättning
DagskasseinsättningBankkassa Över disk hos bankkontor
DagskasseinsättningServiceboxServicebox som möjliggör insättning
PosttjänsterFöretagscenter
PosttjänsterPaketautomat
PosttjänsterPaketombud
PosttjänsterUtlämning
DrivmedelBensin
DrivmedelDiesel
DrivmedelE85
DrivmedelUppgift saknas
ApoteksvarorApotek
ApoteksvarorApoteksombud
Dagligvaror fullsortimentDagligvaror
Dagligvaror ej fullsortimentDagligvaror
activeboolObligatoriskAnger om servicen tillfälligt är inaktiv, ex. säsongsbutik som bara är öppen under sommarhalvåret.
yearintFrivillig (Sätts till nutid)

Det år servicen tillhör. Default är 0 vilket motsvarar aktuellt år.
En service kan bara tillhöra ett år, så vid redigering av historiskt data måste en service skapas för varje år.
För att skapa, uppdatera och radera historiskt data krävs utökad behörighet.

Vid varje årsskifte körs en intern process som arkiverar det gångna årets service.
Då skapas det en kopia av varje service som sedan tilldelas det gångna årets årtal.

timelinessDatedateFrivilligSenast uppdaterad.
För aktuellt år måste datumet ligga inom intervallet xxxx-01-01 till aktuellt datum.
För historiskt data ska datumet ligga inom året.


GetService (hämta en service)

Request

GET /api/services/30000 HTTP/1.1
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

Response 200 OK

HTTP/1.1 200 OK
Content-Type: application/json

{
  "type": "service",
  "id": 30000,
  "data": {
	"attributes": {
	  "id": 30000,
  	  "providerId": 7000,
	  "servicePrincipalId": 20,
	  "serviceTypeId": 2,
	  "forms": ["Bankkassa med kontanter","Bankkassa mot bankkonto/kort"],
	  "properties": null,
	  "active": true,
	  "year": 0,
	  "timelinessDate": "2019-01-20T00:00:00"
	}
  }
}

Response 404 Not Found

HTTP/1.1 404 Not Found
Content-Type: application/json

{
  "errors": [{
    "detail": "Requested service not found"
  }]
}

CreateService (skapa en ny service)

Request

POST /api/services HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

{
  "data": {
    "type": "service",
    "attributes": {
  	  "providerId": 7000,
	  "servicePrincipalId": 123,
	  "serviceTypeId": 7,
	  "forms": [],
	  "properties": {
	    "revenue": 250000 
      },
	  "active": true,
	  "timelinessDate": "2019-01-11T00:00:00+01:00"
	}
  }
}

Response 201 Created

HTTP/1.1 201 Created
Content-Type: application/json

{
  "data": {
    "type": "service",
    "id": 30000,
    "attributes": {
	  "id": 30000,
	  "providerId": "7000",
	  "servicePrincipalId": "123",
	  "serviceTypeId": "7",
	  "forms": [],
	  "properties": {
	    "revenue": 250000 
      },
	  "active": true,
	  "year": 0,
      "timelinessDate": "2019-01-11T00:00:00+01:00"
	}
  }
}

Response 409 Conflict

HTTP/1.1 409 Conflict
Content-Type: application/json

{
  "errors": [{
    "detail": "Truck diesel is not a valid form for service type Kontantuttag"
  }]
}

UpdateService (uppdatera en befintlig service)

Request

PATCH /api/services/30000 HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...
 
{
  "data": {
    "type": "service",
    "id": 30000,
    "attributes": {
	  "providerId": "7000",
	  "servicePrincipalId": "123",
	  "serviceTypeId": "7",
	  "forms": ['Dagligvaror'],
	  "properties": {
	    "revenue": 250000 
      },
	  "active": true,
	  "timelinessDate": "2019-01-11T00:00:00+01:00"
    }
  }
}

Response 200 OK

HTTP/1.1 200 OK
Content-Type: application/json

{
  "data": {
    "type": "service",
    "id": 30000,
    "attributes": {
      "id": 30000,
	  "providerId": "7000",
	  "servicePrincipalId": "123",
	  "serviceTypeId": "7",
	  "forms": ['Dagligvaror'],
	  "properties": {
	    "revenue": 250000 
      },
	  "active": true,
      "year": 0,
	  "timelinessDate": "2019-01-11T00:00:00+01:00"
    }
  }
}

Response 404 Not Found

HTTP/1.1 404 Not Found
Content-Type: application/json

{
  "errors": [{
    "detail": "Requested service not found"
  }]
}

Response 409 Conflict

HTTP/1.1 409 Conflict
Content-Type: application/json

{
  "errors": [{
    detail: "No principal with id 123 exists."
  }]
}

DeleteService (ta bort en befintlig service)

Request

DELETE /api/services/30000 HTTP/1.1
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

Responses 200 OK

HTTP/1.1 200 Ok
Content-Type: application/json

{}

Response 404 Not Found

HTTP/1.1 404 Not Found
Content-Type: application/json

{
  "errors": [{
    "detail": "Service not found"
  }]
}

GetServicesByPrincipal (hämta en lista med all service som ägs av en huvudman)

Request

GET /api/services?principalId=20 HTTP/1.1
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

Response 200 OK

HTTP/1.1 200 OK
Content-Type: application/json

{
  "data": [{
	"attributes": {
	  "id": 30000,
  	  "providerId": 7000,
	  "servicePrincipalId": 20,
	  "serviceTypeId": 2,
	  "forms": ["Bankkassa med kontanter","Bankkassa mot bankkonto/kort"],
	  "properties": {
	     "lst": false
      },
	  "active": true,
	  "year": 0,
	  "timelinessDate": "2019-01-20T00:00:00"
	}
  }, {
	"attributes": {
	  "id": 30001,
  	  "providerId": 7000,
	  "servicePrincipalId": 20,
	  "serviceTypeId": 1,
	  "forms": ["Uttagsautomat"],
	  "properties": {
         "lst": false,
         "ticketsRequired": false
      },
	  "active": true,
	  "year": 0,
	  "timelinessDate": "2019-01-20T00:00:00"
	}
  }]
}

FindServicesByProperty (hämta en lista med service filtrerat på ett "nyckel/värde"-par i attributet properties)

ParameterTypKravBeskrivning
keystring

obligatorisk

Nyckeln i properties
valuestring

obligatorisk

Nyckelns värde
yearintfrivilligDet år servicen tillhör. Default är 0 vilket motsvarar aktuellt år.
limitint

frivillig

Anger hur många serviceobjekt som ska hämtas åt gången

Request

GET /api/services/property/?key=externalId&value=123456&limit=2 HTTP/1.1
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

Response 200 OK

HTTP/1.1 200 OK
Content-Type: application/json

{
  "data": [{
	"attributes": {
	  "id": 30000,
  	  "providerId": 7000,
	  "servicePrincipalId": 20,
	  "serviceTypeId": 2,
	  "forms": ["Bankkassa med kontanter","Bankkassa mot bankkonto/kort"],
	  "properties": {
	     "externalId": '123456'
      },
	  "active": true,
	  "year": 0,
	  "timelinessDate": "2019-01-20T00:00:00"
	}
  }]
}

Servicetype (typ av service) 

Beskrivning av attribut

NamnTypBeskrivning
idintServicetypens id, genereras av servern.
namestring

Servicetyp är den typ av betaltjänst som erbjuds: 

  • Kontantuttag (Servicetypen kontantuttag avser tillgänglig tjänst i form av permanenta inrättningar för kontantuttag, såsom uttagsautomater, instituts eller filialers kontor och livsmedelsbutiker (ingår inte i grundläggande betaltjänster), i vilka konsumenter kan ta ut kontanter från ett betalkonto med grundläggande funktioner i institutet eller filialen).

  • Betalningsförmedling (Servicetypen betalningsförmedling avser tillgänglig tjänst i form av permanenta inrättningar för betalningsförmedling såsom instituts eller filialers kontor, i vilka konsumenter kan betala räkningar).

  • Dagskasseinsättning (Servicetypen dagskasseinsättning avser tillgänglig tjänst i form av permanenta inrättningar för dagskasseinsättningar, såsom insättningsautomater eller instituts eller filialers kontor, i vilka företag kan sätta in kontanter som härrör från verksamheten på ett betalkonto i institutet eller filialen).

GetServiceType (hämta en servicetyp)

Request

GET /api/servicetypes/7 HTTP/1.1
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

Response 200 OK

HTTP/1.1 200 OK
Content-Type: application/json

{
  "data": {
    "type": "serviceType",
    "id": 7,
    "attributes": {
      "id": 7,
      "name": "Dagligvaror"
    }
  }
}

Response 404 Not Found

HTTP/1.1 404 Not Found
Content-Type: application/json

{
  "errors": [{
    "detail": "Requested servicetype not found"
  }]
}

GetAllServiceTypes (hämta en lista med alla servicetyper)

Request

GET /api/servicetypes/ HTTP/1.1
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

Response 200 OK

HTTP/1.1 200 OK
Content-Type: application/json

{
  "data": [{
    "type": "serviceType",
    "id": 1,
    "attributes": {
      "id": 1,
      "name": "Kontantuttag"
    }
  },
  //...
  {
    "type": "serviceType",
    "id": 7,
    "attributes": {
      "id": 7,
      "name": "Dagligvaror"
    }
  }
}

ServicePrincipal (huvudman) 

Beskrivning av attribut

NamnTypKrav vid update/createBeskrivning
idintGenererasHuvudmannens id, genereras av servern.
namestringObligatorisk

Huvudmannens namn.

GetPrincipal (hämta en huvudman)

Request

GET /api/serviceprincipals/30 HTTP/1.1
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

Response 200 OK

HTTP/1.1 200 OK
Content-Type: application/json

{
  "data": {
    "type": "servicePrincipal",
    "id": 7,
    "attributes": {
      "id": 7,
      "name": "Dagligvaror"
    }
  }
}

Response 404 Not Found

HTTP/1.1 404 Not Found
Content-Type: application/json

{
  "errors": [{
    "detail": "Requested service principal not found"
  }]
}

GetAllServicePrincipals (hämtar en lista med alla huvudmän)

Request

GET /api/serviceprincipals/ HTTP/1.1
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

Response 200 OK

HTTP/1.1 200 OK
Content-Type: application/json

{
  "data": [{
    "type": "servicePrincipal",
    "id": 1,
    "attributes": {
      "id": 1,
      "name": "Gulf - EMAB AB"
    }
  },
  //...
  {
    "type": "servicePrincipal",
    "id": 40,
    "attributes": {
      "id": 40,
      "name": "Nära Dej"
    }
  }
}

CreatePrincipal (skapa en ny huvudman)

Request

POST /api/serviceprincipals HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

{
  "data": {
    "type": "servicePrincipal",
    "attributes": {
  	  "name": "ICA Sverige AB"
	}
  }
}

Response 201 Created

HTTP/1.1 201 Created
Content-Type: application/json

{
  "data": {
    "type": "servicePrincipal",
	"id": 40,
    "attributes": {
	  "id": 40,
  	  "name": "ICA Sverige AB"
	}
  }
}

Response 409 Conflict

HTTP/1.1 409 Conflict
Content-Type: application/json

{
  "errors": [{
    "detail": "ICA Sverige AB already exists"
  }]
}

Serviceform (formen av den service som utförs) 

Beskrivning av attribut

NamnTypKrav vid update/createBeskrivning
idintGenererasServiceformens id, genereras av servern.
serviceTypeIdintObligatoriskId till den servicetypen som serviceformen tillhör.
namestringObligatorisk

Namnet på serviceformen.

GetServiceForm (hämta en serviceform)

Request

GET /api/serviceform/19 HTTP/1.1
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

Response 200 OK

HTTP/1.1 200 OK
Content-Type: application/json

{
  "data": {
    "type": "serviceForm",
    "id": 19,
    "attributes": {
      "id": 19,
	  "name": "Kortterminal"
	  "serviceTypeId": 1,
    }
  }
}

Response 404 Not Found

HTTP/1.1 404 Not Found
Content-Type: application/json

{
  "errors": [{
    "detail": "Requested servicetype not found"
  }]
}

GetAllServiceForms (hämta en lista med alla serviceformer)

Request

GET /api/serviceforms/ HTTP/1.1
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

Response 200 OK

HTTP/1.1 200 OK
Content-Type: application/json

{
  "data": [{
    "type": "serviceForm",
    "id": 21,
    "attributes": {
      "id": 21,
      "name": "Bankkassa",
      "serviceTypeId": 1
    }
  },
  //...
  {
    "type": "serviceForm",
    "id": 10,
    "attributes": {
      "id": 10,
      "name": "Dagligvaror",
	  "serviceTypeId": 3
    }
  }
}

Organisation 

Beskrivning av attribut

NamnTypBeskrivning

id

intOrganisationens id, genereras av servern.

name

stringNamnet på organisationen (ex. Testbanken AB).

organisationNumber

stringOrganisationsnummer (unik).

username

stringDet användarnamn organisationen använder för att registrera uppdaterare i administrationsportalen.
emailstringE-postadress till ovan användare.

isSupplier

boolAnger om organisationen är ett kreditinstitut.

isPrincipal

boolAnger om organisationen är en huvudman.
servicePrincipalIdintOm organisationen är en huvudman anges huvudmannens id-nummer här.

activeSupplier

bool

Anger om organisationen är ett aktivt kreditinstitut.

inactiveSupplierCaseNumberstringOm organisationen sätts till inaktivt kreditinstitut, anges ärendenumret här.
activePrincipalbool

Anger om organisationen är en aktiv huvudman.

inactivePrincipalCaseNumberstringOm organisationen sätt till inaktiv huvudman, anges ärendenumret här.
submittedboolNär alla uppdatering är klar sätts submitted till true och redigeringsmöjligheterna blir låsta.

GetOrganisation (hämta en organisation)

Request

GET /api/organisations/7000 HTTP/1.1
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

Response 200 OK

HTTP/1.1 200 OK
Content-Type: application/json

{
	"attributes": {
		"id": 6,
		"name": "Testbanken AB",
		"organisationNumber": "12345678-1234",
		"servicePrincipalId": 245,
		"username": "lassekongo",
		"email": "lassekongo@mail.com",
		"isSupplier": true,
		"isPrincipal": true,
		"activePrincipal": true,
		"activeSupplier": true,
		"submitted": false,
		"inactiveSupplierCaseNumber": "",
		"inactivePrincipalCaseNumber": ""
	},
	"id": 6,
	"type": "organisation"
}

Response 404 Not Found

HTTP/1.1 404 Not Found
Content-Type: application/json

{
  "errors": [{
    "detail": "Ingen organisation med id 123 hittades."
  }]
}

ServiceFormTemplate

Beskrivning av attribut

NamnTypKrav vid update/createBeskrivning

id

intGenererasMallens id, genereras av servern.

principalOrganisationId

intObligatoriskId till den organisation som äger mallen, se Organisation 

serviceTypeId

intObligatoriskId till typen av service som utförs, se Servicetyp. 

serviceFormId

intObligatoriskId till formen som utförs, se Serviceform.

openHoursPerWeek

intFrivilligÖppettider anges i timmar per vecka under normalvecka. Med normalvecka avses en vecka som består av fem helgfria dagar samt lördag och söndag utan extra helgdagar, under normalsäsong. Om platsen för kontanttjänsten finns i en lokal eller inrättning som har kortare öppettider än platsen anges lokalens eller inrättningens öppettider. 
Giltiga värden är 0 till 168.

closedWeeksPerYear

intFrivilligAnges i antal veckor per år som platsen är stängd.
Giltiga värden är 0 till 53.
advancedOpenHourDescriptionstringFrivilligFält där avgiftsmodellen kan förklaras i fritext om den inte passar in i ovanstående alternativ eller om det finns olika avgifter för olika kunder.

withdrawalLimit

intFrivillig

Ange högsta tillåtna belopp per uttag, som du som huvudman tillåter. Ange 0 om inte maxbelopp tillämpas.

minFlatFeeintFrivilligFylls i med lägsta fasta avgift. Beloppet anges i kronor.
minPercentageFeefloatFrivillig

Fylls i med lägsta rörliga avgift i form av procent av uttag. Anges i procent, giltiga värden är 0 till 100.

maxFlatFeeintFrivilligFylls i med högsta fasta avgift. Beloppet anges i kronor.
maxPercentageFeefloatFrivilligFylls i med högsta rörliga avgift i form av procent av uttag. Anges i procent, giltiga värden är 0 till 100.
advancedFeeDescriptionstringFrivilligFält där avgiftsmodellen kan förklaras i fritext om den inte passar in i ovanstående alternativ eller det finns olika avgifter för olika kunder.
depositLimitintFrivilligAnge högsta tillåtna belopp per insättning, som du som huvudman tillåter. Beloppet ska anges i kronor. Ange 0 om inte maxbelopp tillämpas.
withdrawalLimitDescriptionstringFrivilligFält där modell för lägsta maxbelopp för insättning eller uttag kan förklaras i fritext om den inte passar in i ovanstående alternativ.
weeklyDepositLimitintFrivilligAnge högsta tillåtna belopp, som du som huvudman tillåter, att kunden får sätta in på en vecka. Beloppet ska anges i kronor. Ange 0 om inte maxbelopp tillämpas.

accessBarrier

boolFrivillig

Tillträdeshinder. Sant om det krävs inträdesbiljett och/eller specifik behörighet till område/lokal.

Om tillträdeshinder är sant ska attributet accessBarrierDescription anges.

accessBarrierDescriptionstringFrivilligFält där tillträdeshindret kan förklaras i fritext.

GetServiceFormTemplate (hämta en en mall)

Request

GET /api/serviceformtemplates/12 HTTP/1.1
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

Response 200 OK

HTTP/1.1 200 OK
Content-Type: application/json
 

GetServiceFormTemplatesByOrganisation (hämta de mallar som ägs av organisationen)

Request

GET /api/serviceformtemplates/principal/6 HTTP/1.1
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

Response 200 OK

HTTP/1.1 200 OK
Content-Type: application/json
 

UpdateServiceFormTemplate (Uppdatera en mall)

Request

PATCH /api/serviceformtemplates/12 HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

{
   "data": {}
}

Response 200 OK

HTTP/1.1 200 OK
Content-Type: application/json
 

ServiceFormCustomization

Beskrivning av attribut

NamnTypKrav vid update/createBeskrivning

id

intGenererasAnpassningens id, genereras av servern.

serviceId

intObligatoriskId till den service som anpassningen hör till. 

serviceFormId

intObligatoriskId till den serviceform som anpassningen hör till.

accessBarrier

boolFrivillig

Tillträdeshinder. Sant om det krävs inträdesbiljett och/eller specifik behörighet till område/lokal.

Om tillträdeshinder är sant ska attributet accessBarrierDescription anges.

accessBarrierDescriptionstringFrivilligFält där tillträdeshindret kan förklaras i fritext.

openHoursPerWeek

intFrivilligÖppettider anges i timmar per vecka under normalvecka. Med normalvecka avses en vecka som består av fem helgfria dagar samt lördag och söndag utan extra helgdagar, under normalsäsong. Om platsen för kontanttjänsten finns i en lokal eller inrättning som har kortare öppettider än platsen anges lokalens eller inrättningens öppettider. 
Giltiga värden är 0 till 168.

closedWeeksPerYear

intFrivilligAnges i antal veckor per år som platsen är stängd.
Giltiga värden är 0 till 53.
advancedOpenHourDescriptionstringFrivilligFält där avgiftsmodellen kan förklaras i fritext om den inte passar in i ovanstående alternativ eller om det finns olika avgifter för olika kunder.

withdrawalLimit

intFrivillig

Ange högsta tillåtna belopp per uttag, som du som huvudman tillåter. Ange 0 om inte maxbelopp tillämpas.

minFlatFeeintFrivilligFylls i med lägsta fasta avgift. Beloppet anges i kronor.
minPercentageFeefloatFrivillig

Fylls i med lägsta rörliga avgift i form av procent av uttag. Anges i procent, giltiga värden är 0 till 100.

maxFlatFeeintFrivilligFylls i med högsta fasta avgift. Beloppet anges i kronor.
maxPercentageFeefloatFrivilligFylls i med högsta rörliga avgift i form av procent av uttag. Anges i procent, giltiga värden är 0 till 100.
advancedFeeDescriptionstringFrivilligFält där avgiftsmodellen kan förklaras i fritext om den inte passar in i ovanstående alternativ eller det finns olika avgifter för olika kunder.
depositLimitintFrivilligAnge högsta tillåtna belopp per insättning, som du som huvudman tillåter. Beloppet ska anges i kronor. Ange 0 om inte maxbelopp tillämpas.
withdrawalLimitDescriptionstringFrivilligFält där modell för lägsta maxbelopp för uttag eller insättning kan förklaras i fritext om den inte passar in i ovanstående alternativ. Ange 0 om inte maxbelopp tillämpas.
weeklyDepositLimitintFrivilligAnge högsta tillåtna belopp, som du som huvudman tillåter, att kunden får sätta in på en vecka. Beloppet ska anges i kronor. Ange 0 om inte maxbelopp tillämpas.

ServiceSupplierModel

Beskrivning av attribut

Namn

Typ

Krav vid update/create

Beskrivning

id

intGenererasModellens id, genereras av servern.

supplierOrganisationId

intObligatoriskOrganisations-id till det kreditinstitut eller filial till utländskt kreditinstitut som omfattas av skyldigheten att tillhandahålla kontanttjänster.

principalOrganisationId

intObligatoriskOrganisations-id till den huvudman som driver eller på annat sätt råder över kontanttjänsten.

serviceTypeId

intObligatoriskServicetyps-id till den typ av betaltjänst som erbjuds (kontantuttag, dagskasseinsättning eller betalningsförmedling).

serviceFormId

intObligatoriskServiceforms-id till den serviceform modellen gäller.
minFlatFeeintObligatorisk

Avgift per uttag (fast avgift).
Totala lägsta fasta avgift som era slutkunder får betala när de använder den aktuella betaltjänsten hos ovan vald huvudman. Belopp anges i kronor.

minPercentageFeefloatObligatorisk

Avgift per uttag (rörlig avgift).
Totala lägsta rörliga avgift som era slutkunder får betala när de använder den aktuella betaltjänsten hos ovan vald huvudman. Värdet anges i %.

maxFlatFeeintObligatorisk

Avgift per uttag (fast avgift).

Totala högsta fasta avgift som era slutkunder får betala när de använder den aktuella betaltjänsten hos ovan vald huvudman. Belopp anges i kronor.

maxPercentageFeefloatObligatorisk

Avgift per uttag (rörlig avgift).

Totala högsta rörliga avgift som era slutkunder får betala när de använder den aktuella betaltjänsten hos ovan vald huvudman. Värdet anges i %.

advancedWithdrawalFeeDescriptionstringFrivilligFält där avgiftsmodellen kan förklaras i fritext om den inte passar in i ovanstående alternativ.
withdrawalLimitintFrivilligAnge högsta tillåtna belopp per uttag för era slutkunder när de gör uttag från ert betalkonto genom tjänst hos aktuell huvudman och för vald serviceform. Beakta gränser för maxbelopp hos er och hos huvudmannen (dvs välj det lägsta av de två). Beloppet ska anges i kronor. Ange 0 om inte maxbelopp tillämpas.
weeklyDepositLimitintFrivilligAnge högsta tillåtna belopp som era slutkunder får sätta in på en vecka på betalkonto hos er genom tjänst hos ovan vald huvudman och för ovan vald serviceform. Beakta gällande maxbelopp hos er och hos huvudmannen (dvs välj det lägsta av de två). Beloppet anges i kronor. Ange 0 om inte maxbelopp tillämpas.
depositLimitintFrivilligAnge högsta tillåtna belopp per insättning som era slutkunder får sätta in på betalkonto hos er genom tjänst hos ovan vald huvudman och för ovan serviceform. Beakta gällande maxbelopp hos er och hos huvudmannen (dvs välj det lägsta av de två). Beloppet anges i kronor. Ange 0 om inte maxbelopp tillämpas.
withdrawalLimitDescriptionstringFrivilligFält där modell för lägsta maxbelopp för insättning eller uttag kan förklaras i fritext om den inte passar in i ovanstående alternativ.
includedServiceIdsint[]FrivilligInkludera bara specifika platser för kontanttjänster hos vald huvudman. Listan innehåller id till service.

Address

Beskrivning av attribut

NamnTypBeskrivning
idintAdressens interna id.
addressstring

Postadress

postal_codeintPostnummer
post_townstringPostort
formatted_addressstringFormaterad adress
xdoubleX-koordinat i SWEREF 99
ydoubleY-koordinat i SWEREF 99

FindByAttributes (Söker adress med hjälp av postadress, postnummer och postort)

ParameterTypKravBeskrivning
addressstring

obligatorisk

Postadress
postalcodeint

obligatorisk

Postnummer
posttownstring

obligatorisk

Postort

Request

GET /api/geocode/findByAttributes/?address=storgatan%2044&postalCode=11455&postTown=stockholm HTTP/1.1
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

Response 200 OK

FindByCoordinate (Söker närmaste adress från en koordinat i SWEREF 99)

ParameterTypKravBeskrivning
xint

obligatorisk

X-koordinat i SWEREF 99 TM (EPSG 3006)
yint

obligatorisk

Y-koordinat i SWEREF 99 TM (EPSG 3006)

Request

GET /api/geocode/findByCoordinate/?x=600000&y=7000000 HTTP/1.1
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

Response 200 OK

HTTP/1.1 200 OK
Content-Type: application/json

{  
  "data": {  
    "attributes": {  
      "id": 379665,
      "address": "Storgatan 44",
      "postal_code": 11455,
      "post_town": "Stockholm",
      "formatted_address": "Storgatan 44, 114 55 Stockholm",
      "x": 600002.88,
      "y": 7000010.607
    },
    "id": 379665,
    "type": "addressPlace"
  }
}

FindByPattern (Söker adresser med hjälp av fritext, returnerar en lista med adresser sorterad på relevans)

ParameterTypKravBeskrivning
patternstring

required

Fritextfält, t. ex. "Storgatan 44, Stockholm"
limitint

required

Max antal sökträffar som ska returneras

Request

GET /api/geocode/findByPattern/?pattern=storgatan%2044%2C%20stockholm&limit=10 HTTP/1.1
Accept: application/json
Authorization: Bearer imSXTs2aiadQhIXffziFCO3rF...

Response 200 OK

HTTP/1.1 200 OK
Content-Type: application/json

{  
  "data": [{  
    "attributes": {  
      "id": 379665,
      "address": "Storgatan 44",
      "postal_code": 11455,
      "post_town": "Stockholm",
      "formatted_address": "Storgatan 44, 114 55 Stockholm",
      "x": 675797.33,
      "y": 6581265.607
    },
    "id": 379665,
    "type": "addressPlace"
  }, 
  {  
    "attributes": {  
      "id": 1517317,
      "address": "Storgatan 44A",
      "postal_code": 11455,
      "post_town": "Stockholm",
      "formatted_address": "Storgatan 44A, 114 55 Stockholm",
      "x": 675801.006,
      "y": 6581247.599
    },
    "id": 1517317,
    "type": "addressPlace"
  }]
}

Kodexempel

Python3

Logga in, skapa och hämta
#-*- coding: utf-8 -*-
import urllib.request
import urllib.error
import urllib.parse
import json
 
BASE_URL = 'https://kontantanalys.tillvaxtverket.se/test'
 
def acquire_token(username, password):
    """ Login and acquire a valid token """
    url = BASE_URL + '/Token'
    data = {
        'grant_type': 'password',
        'username': username,
        'password': password
    }
    opener = urllib.request.build_opener()
    response = opener.open(url, urllib.parse.urlencode(data).encode("utf-8"))
 
    if response.getcode() == 200:
        content = response.read()
        data = json.loads(content)
        return data['access_token']
 
    return None
 
def create_provider(provider, token):
    headers = {
        'Authorization': 'Bearer %s' % token,
        'Content-Type': 'application/json',
        'Accept': 'application/json'
    }
    envelope = {
        "data": provider
    }
 
    url = BASE_URL + '/api/providers/'
    data = json.dumps(envelope).encode('utf8')
    req = urllib.request.Request(url, headers=headers)
    try:
        response = urllib.request.urlopen(req, data=data)
        content = response.read()
        new_object = json.loads(content)
        return new_object['data']
    except urllib.error.HTTPError as e:
        content = e.read()
        if content:
            errors = json.loads(content)
            print ('Error (%d) create provider' % e.code)
            for error in errors['errors']:
                print (error)
        else:
            print ('Error (%d) create provider' % e.code)
 
    return None
 
def find_provider(provider_id, token):
    """ Get provider by id """
    opener = urllib.request.build_opener()
    opener.addheaders = [('Authorization', 'Bearer %s' % token)]
    url = BASE_URL + '/api/Providers/%d' % provider_id
    response = opener.open(url)
    content = response.read()
    data = json.loads(content)
    return data['data']
 
def main():
    token = acquire_token('testbanken', 'Sommar&sol2020')
     
    provider = {
        'type': 'provider',
        'attributes': {
            'name': 'INGO Örebro, Adolfsbergsvägen',
            'visitingAddress': 'Adolfsbergsvägen 4',
            'postalCode': '702 27',
            'postTown': 'ÖREBRO',
            'x': 509886.4,
            'y': 6568855.5
        }
    }
    new_provider = create_provider(provider, token)
    if new_provider:
        provider = find_provider(new_provider['id'], token)
        assert provider['attributes']['name'] == new_provider['attributes']['name']
 
if __name__== "__main__":
    main()

C#

Logga in, skapa och hämta
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Web;
using Newtonsoft.Json;

namespace PiPoS.Examples
{
    public class ApiExamples
    {
		static readonly string BASE_URL = "https://kontantanalys.tillvaxtverket.se/test";

		public static void Main(string[] args)
        {
			var token = AcquireToken("testbanken", "Sommar&sol2020");
            var provider = new Provider {
                Name = "INGO Örebro, Adolfsbergsvägen",
                VisitingAddress = "Adolfsbergsvägen 4",
                PostalCode = "702 27",
                PostTown = "ÖREBRO",
                X = 509886.4,
                Y = 6568855.5
            };
            
            var newProvider = CreateProvider(provider, token);
            provider = FindProvider(newProvider.Id, token);
            System.Diagnostics.Debug.Assert(newProvider.Name == provider.Name);
		}

		static string AcquireToken(string username, string password)
        {
            string token = string.Empty;
            using (var client = new WebClient())
            {
                client.Headers.Add(HttpRequestHeader.ContentType, "application/x-www-form-urlencoded");
                var formData = string.Format("grant_type=password&username={0}&password={1}",
                    HttpUtility.UrlEncode(username),
                    HttpUtility.UrlEncode(password)
                );
                var htmlResult = client.UploadString(BASE_URL + "/Token", formData);
                var json = JsonConvert.DeserializeObject<Dictionary<string, object>>(htmlResult);

                if (json.ContainsKey("access_token"))
                {
                    token = json["access_token"] as string;
                }
            }
            return token;
        }

		static Provider CreateProvider(Provider provider, string token)
        {
            using (var client = new WebClient())
            {
                client.Headers.Add(HttpRequestHeader.Authorization, string.Format("Bearer {0}", token));
                client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
                client.Headers.Add(HttpRequestHeader.Accept, "application/json");
 
                var envelope = new Envelope<Provider>
                {
                    Data = new Data<Provider>
                    {
                        Attributes = provider,
                        Type = "provider"
                    }
                };
                     
                var json = JsonConvert.SerializeObject(envelope);
                var result = string.Empty;

                try
                {
                    result = client.UploadString(BASE_URL + "/api/providers/", json);
                }
                catch (WebException exception)
                {
                    var responseStream = exception.Response?.GetResponseStream();
                    if (responseStream != null)
                    {
                        using (var reader = new StreamReader(responseStream))
                        {
                            var responseText = reader.ReadToEnd();
                            if (!string.IsNullOrEmpty(responseText))
                            {
                                try
                                {
                                    var responseData = JsonConvert.DeserializeObject<Error>(responseText);
                                    foreach (var error in responseData?.Errors)
                                    {
                                        Console.Error.WriteLine($"Error:\t{error}");
                                    }
                                }
                                catch (JsonReaderException)
                                {
                                    Console.Error.WriteLine(responseText);
                                }
                                
                            }
                        }
                    }
                    throw exception;
                }
                                  
                var newProvider = JsonConvert
                    .DeserializeObject<Envelope<Provider>>(result)
                    .Data
                    .Attributes;
                return newProvider;
            }
        }

		static Provider FindProvider(int providerId, string token)
        {
            using (var client = new WebClient())
            {
                client.Headers.Add(HttpRequestHeader.Authorization, string.Format("Bearer {0}", token));
                using (var data = client.OpenRead(BASE_URL + $"/api/providers/{providerId}"))
                using (var reader = new StreamReader(data))
                {
                    var provider = JsonConvert
                        .DeserializeObject<Envelope<Provider>>(reader.ReadToEnd())
                        .Data
                        .Attributes;
                    return provider;
                }
            }
        }

		public class Envelope<TEntity>
        {
            [JsonProperty(PropertyName = "data")]
            public Data<TEntity> Data { get; set; }
        }

        public class Data<TEntity>
        {
            [JsonProperty(PropertyName = "attributes")]
            public TEntity Attributes { get; set; }

            [JsonProperty(PropertyName = "id")]
            public int Id { get; set; }

            [JsonProperty(PropertyName = "type")]
            public string Type { get; set; }
        }

        public class Provider
        {
            [JsonProperty(PropertyName = "id")]
            public int Id { get; set; }

            [JsonProperty(PropertyName = "name")]
            public string Name { get; set; }

            [JsonProperty(PropertyName = "code")]
            public string Code { get; set; }

            [JsonProperty(PropertyName = "x")]
            public double X { get; set; }

            [JsonProperty(PropertyName = "y")]
            public double Y { get; set; }

            [JsonProperty(PropertyName = "visitingAddress")]
            public string VisitingAddress { get; set; }

            [JsonProperty(PropertyName = "postalCode")]
            public string PostalCode { get; set; }

            [JsonProperty(PropertyName = "postTown")]
            public string PostTown { get; set; }

            [JsonIgnore]
            public string TypeName => "provider";
        }

        public class Error
        {
            [JsonProperty(PropertyName = "errors")]
            public List<string> Errors { get; set; }
        }
	}
}
  • No labels