gRPC Introduktion

Avidentifiera API via gRPC erbjuder ett högpresterande, typsäkert alternativ till REST för server-till-server-kommunikation. API:et tar emot text, PDF eller DOCX och returnerar en avidentifierad version baserat på regelstyrd behandling av personuppgifter.

Tjänsten RedactionService har två huvudsakliga RPC-metoder:

  • RedactFile – tar emot en PDF eller DOCX (Word) som bytes eller Base64 och returnerar den avidentifierade filen på samma sätt.
  • RedactText – tar en textsträng och returnerar den avidentifierade texten.

Endpoint (Native & Web):

https://api.avidentifiera.se:50051

Direkt in, direkt ut – inga känsliga dokument lagras

Precis som med vårt REST-API har vi valt en synkron modell för datasäkerhet och enkelhet. Dokumentet skickas i din begäran, bearbetas helt i minnet och det avidentifierade resultatet skickas tillbaka i samma anrop. Vi lagrar aldrig ditt originaldokument på våra servrar.

För verksamheter som hanterar sekretessreglerade handlingar betyder detta att du skickar ett dokument och får tillbaka en avidentifierad version direkt – utan att vi behöver spara ditt original.

Proto-definition

Du kan alltid hämta den senaste kontraktsdefinitionen (.proto) här:

https://api.avidentifiera.se/grpc/v1/redaction.proto


Klient-setup

För att komma igång behöver du gRPC-verktyg för ditt språk för att generera klientkod från vår .proto-fil. Här är de vanligaste paketen och kommandona.

<!-- Lägg till i din .csproj-fil -->
<ItemGroup>
  <PackageReference Include="Grpc.Net.Client" Version="2.62.0" />
  <PackageReference Include="Grpc.Net.Client.Web" Version="2.62.0" />
  <PackageReference Include="Google.Protobuf" Version="3.25.3" />
  <PackageReference Include="Grpc.Tools" Version="2.62.0" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
  <Protobuf Include="Protos\redaction.v1.proto" GrpcServices="Client" />
</ItemGroup>
# 1. Installera paket
pip install grpcio grpcio-tools

# 2. Ladda ner .proto-filen och generera kod
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. redaction.v1.proto
# För native gRPC (backend)
npm install @grpc/grpc-js @grpc/proto-loader

# För gRPC-Web (webbläsare)
npm install grpc-web google-protobuf

Autentisering

Varje anrop måste innehålla en giltig API-nyckel som metadata med nyckeln authorization och värdet Bearer <din-nyckel>. Om nyckeln saknas eller är ogiltig returneras statuskoden UNAUTHENTICATED.

var metadata = new Grpc.Core.Metadata { { "Authorization", "Bearer live_xxx..." } };
var response = await client.RedactTextAsync(request, metadata);
metadata = [('authorization', 'Bearer live_xxx...')]
response = stub.RedactText(request, metadata=metadata)
const md = new grpc.Metadata();
md.set('authorization', 'Bearer live_xxx...');
client.RedactText(request, md, (err, resp) => { /* ... */ });

Avidentifiera fil

RPCRedactFile

Skicka en PDF eller DOCX och få tillbaka en avidentifierad version. Filen kan skickas som råa bytes eller som en Base64-kodad sträng.

Request: RedactFileRequest

FältBeskrivning
fileName
string
Filnamn, t.ex. "dokument.pdf". Används för att avgöra filtyp.
fileBytes
bytes
Filens innehåll som en byte-array. Använd antingen detta fält eller fileBase64.
fileBase64
string
Filens innehåll som en Base64-kodad sträng. Använd antingen detta fält eller fileBytes.
options
Options
Valfri konfiguration. Se Regelkonfiguration.

Response: RedactFileResponse

FältBeskrivning
took
int64
Total bearbetningstid på servern i millisekunder.
result
FileResult
Innehåller den avidentifierade filen som redactedFileBytes eller redactedFileBase64 (beroende på request), samt funna entities.
using Google.Protobuf;
using Grpc.Core;
using Grpc.Net.Client;
using Grpc.Net.Client.Web;
using Grpc.Redaction.V1;

const string apiKey = "Bearer live_xxx...";
var metadata = new Metadata { { "Authorization", apiKey } };
var grpcWebHandler = new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler());
using var channel = GrpcChannel.ForAddress("https://api.avidentifiera.se:50051", new GrpcChannelOptions { HttpHandler = grpcWebHandler });
var client = new RedactionService.RedactionServiceClient(channel);

var fileBytes = await File.ReadAllBytesAsync("dokument.pdf");
var req = new RedactFileRequest
{
    FileName = "dokument.pdf",
    FileBytes = ByteString.CopyFrom(fileBytes),
    Options = new Options { Entities = { EntityType.Name, EntityType.Address } }
};

var resp = await client.RedactFileAsync(req, metadata);
await File.WriteAllBytesAsync("redacted.pdf", resp.Result.RedactedFileBytes.ToByteArray());
using Google.Protobuf;
using Grpc.Core;
using Grpc.Net.Client;
using Grpc.Redaction.V1;
using System.Net;

const string apiKey = "Bearer live_xxx...";
var metadata = new Metadata { { "Authorization", apiKey } };
var socketsHandler = new SocketsHttpHandler { EnableMultipleHttp2Connections = true };
var httpClient = new HttpClient(socketsHandler) { DefaultRequestVersion = HttpVersion.Version20, DefaultVersionPolicy = HttpVersionPolicy.RequestVersionExact };
using var channel = GrpcChannel.ForAddress("https://api.avidentifiera.se:50051", new GrpcChannelOptions { HttpClient = httpClient });
var client = new RedactionService.RedactionServiceClient(channel);

var fileBytes = await File.ReadAllBytesAsync("dokument.pdf");
var req = new RedactFileRequest
{
    FileName = "dokument.pdf",
    FileBytes = ByteString.CopyFrom(fileBytes),
    Options = new Options { Entities = { EntityType.Name, EntityType.Address } }
};

var resp = await client.RedactFileAsync(req, metadata);
await File.WriteAllBytesAsync("redacted.pdf", resp.Result.RedactedFileBytes.ToByteArray());
import { RedactionServiceClient } from './generated/RedactionServiceClientPb.js';
import { RedactFileRequest, Options, EntityType } from './generated/redaction_v1_pb.js';

const client = new RedactionServiceClient('https://api.avidentifiera.se:50051');
const req = new RedactFileRequest();

// I webbläsare är det vanligast att hantera filen som Base64
const base64String = "JVBERi0xLjQKJ..."; // Din Base64-kodade PDF/DOCX
req.setFileName("dokument.pdf");
req.setFilebase64(base64String);

const options = new Options();
options.addEntities(EntityType.NAME);
options.addEntities(EntityType.ADDRESS);
req.setOptions(options);

const metadata = { 'authorization': 'Bearer live_xxx...' };
client.redactFile(req, metadata, (err, resp) => {
  if (err) return console.error(err);
  
  // Svaret kommer som Base64, som kan användas för att skapa en nedladdningslänk
  const redactedBase64 = resp.getResult().getRedactedfilebase64();
  console.log('Mottog avidentifierad fil som Base64.');
});
import grpc from '@grpc/grpc-js';
import protoLoader from '@grpc/proto-loader';
import fs from 'fs';

const def = protoLoader.loadSync('./Protos/redaction.v1.proto', { keepCase: true, longs: String, enums: String, defaults: true, oneofs: true });
const proto = grpc.loadPackageDefinition(def).grpc.redaction.v1;
const client = new proto.RedactionService('api.avidentifiera.se:50051', grpc.credentials.createSsl());

const md = new grpc.Metadata();
md.set('authorization', 'Bearer live_xxx...');

const bytes = fs.readFileSync('dokument.pdf');
const req = { 
    fileName: 'dokument.pdf', 
    fileBytes: bytes, 
    options: { entities: ['name','address'] } 
};

client.RedactFile(req, md, (err, resp) => {
  if (err) return console.error(err);
  fs.writeFileSync('redacted.pdf', resp.result.redactedFileBytes);
  console.log('Avidentifierad fil sparad som redacted.pdf');
});
import grpc
import redaction_v1_pb2
import redaction_v1_pb2_grpc

API_KEY = "Bearer live_xxx..."
ADDRESS = "api.avidentifiera.se:50051"

def run():
    creds = grpc.ssl_channel_credentials()
    with grpc.secure_channel(ADDRESS, creds) as channel:
        stub = redaction_v1_pb2_grpc.RedactionServiceStub(channel)
        
        with open("dokument.pdf", "rb") as f:
            file_bytes = f.read()
            
        req = redaction_v1_pb2.RedactFileRequest(
            fileName="dokument.pdf",
            fileBytes=file_bytes,
            options=redaction_v1_pb2.Options(entities=[redaction_v1_pb2.EntityType.name, redaction_v1_pb2.EntityType.address])
        )
        
        md = [('authorization', API_KEY)]
        resp = stub.RedactFile(req, metadata=md)
        
        with open("redacted.pdf", "wb") as out:
            out.write(resp.result.redactedFileBytes)
        print("Avidentifierad fil sparad som redacted.pdf")

if __name__ == "__main__":
    run()

Avidentifiera text

RPCRedactText

Skicka en textsträng och få tillbaka en avidentifierad version. Lyckade anrop returnerar status OK.

Request: RedactTextRequest

FältBeskrivning
text
string
Texten som ska avidentifieras. Max 1 000 000 tecken.
options
Options
Valfri konfiguration som styr avidentifieringen. Om den utelämnas används standardprofilen (namn, adress, personnummer maskeras). Se Regelkonfiguration.

Response: RedactTextResponse

FältBeskrivning
took
int64
Total bearbetningstid på servern i millisekunder.
result
TextResult
Innehåller den avidentifierade texten (redactedText) och en lista över funna entiteter (entities).
using Grpc.Core;
using Grpc.Net.Client;
using Grpc.Net.Client.Web;
using Grpc.Redaction.V1;

const string apiKey = "Bearer live_xxx...";
var metadata = new Metadata { { "Authorization", apiKey } };

var grpcWebHandler = new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler());
using var channel = GrpcChannel.ForAddress("https://api.avidentifiera.se:50051", new GrpcChannelOptions { HttpHandler = grpcWebHandler });
var client = new RedactionService.RedactionServiceClient(channel);

var request = new RedactTextRequest
{
    Text = "Mitt namn är Anna Andersson och mitt personnummer är 850612-1234.",
    Options = new Options
    {
        Entities = { EntityType.Name, EntityType.PersonalNumber },
        Rules = new Rules
        {
            Name = new NameRules { Method = Method.ReplaceWithInitials },
            PersonalNumber = new PersonalNumberRules { Method = Method.Remove }
        }
    }
};

var response = await client.RedactTextAsync(request, metadata);
Console.WriteLine(response.Result.RedactedText); // "Mitt namn är A.A och mitt personnummer är ."
using Grpc.Core;
using Grpc.Net.Client;
using Grpc.Redaction.V1;
using System.Net;

const string apiKey = "Bearer live_xxx...";
var metadata = new Metadata { { "Authorization", apiKey } };

var socketsHandler = new SocketsHttpHandler { EnableMultipleHttp2Connections = true };
var httpClient = new HttpClient(socketsHandler) { DefaultRequestVersion = HttpVersion.Version20, DefaultVersionPolicy = HttpVersionPolicy.RequestVersionExact };
using var channel = GrpcChannel.ForAddress("https://api.avidentifiera.se:50051", new GrpcChannelOptions { HttpClient = httpClient });
var client = new RedactionService.RedactionServiceClient(channel);

var request = new RedactTextRequest
{
    Text = "Mitt namn är Anna Andersson och mitt personnummer är 850612-1234.",
    Options = new Options
    {
        Entities = { EntityType.Name, EntityType.PersonalNumber },
        Rules = new Rules
        {
            Name = new NameRules { Method = Method.ReplaceWithInitials },
            PersonalNumber = new PersonalNumberRules { Method = Method.Remove }
        }
    }
};

var response = await client.RedactTextAsync(request, metadata);
Console.WriteLine(response.Result.RedactedText); // "Mitt namn är A.A och mitt personnummer är ."
import { RedactionServiceClient } from './generated/RedactionServiceClientPb.js';
import { RedactTextRequest, Options, Rules, NameRules, PersonalNumberRules, Method, EntityType } from './generated/redaction_v1_pb.js';

const client = new RedactionServiceClient('https://api.avidentifiera.se:50051');
const req = new RedactTextRequest();
req.setText('Mitt namn är Anna Andersson och mitt personnummer är 850612-1234.');

const options = new Options();
options.addEntities(EntityType.NAME);
options.addEntities(EntityType.PERSONALNUMBER);

const rules = new Rules();
const nameRules = new NameRules();
nameRules.setMethod(Method.REPLACEWITHINITIALS);
rules.setName(nameRules);

const pnRules = new PersonalNumberRules();
pnRules.setMethod(Method.REMOVE);
rules.setPersonalnumber(pnRules);

options.setRules(rules);
req.setOptions(options);

const metadata = { 'authorization': 'Bearer live_xxx...' };
client.redactText(req, metadata, (err, resp) => {
  if (err) return console.error(err);
  console.log(resp.getResult().getRedactedText());
});
import grpc from '@grpc/grpc-js';
import protoLoader from '@grpc/proto-loader';

const def = protoLoader.loadSync('./Protos/redaction.v1.proto', { keepCase: true, longs: String, enums: String, defaults: true, oneofs: true });
const proto = grpc.loadPackageDefinition(def).grpc.redaction.v1;
const client = new proto.RedactionService('api.avidentifiera.se:50051', grpc.credentials.createSsl());

const md = new grpc.Metadata();
md.set('authorization', 'Bearer live_xxx...');

const request = {
    text: 'Mitt namn är Anna Andersson och mitt personnummer är 850612-1234.',
    options: {
        entities: ['name', 'personalNumber'],
        rules: {
            name: { method: 'replaceWithInitials' },
            personalNumber: { method: 'remove' }
        }
    }
};

client.RedactText(request, md, (err, resp) => {
  if (err) return console.error(err);
  console.log(resp.result.redactedText);
});
import grpc
import redaction_v1_pb2
import redaction_v1_pb2_grpc

API_KEY = "Bearer live_xxx..."
ADDRESS = "api.avidentifiera.se:50051"

def run():
    creds = grpc.ssl_channel_credentials()
    with grpc.secure_channel(ADDRESS, creds) as channel:
        stub = redaction_v1_pb2_grpc.RedactionServiceStub(channel)
        req = redaction_v1_pb2.RedactTextRequest(
            text="Mitt namn är Anna Andersson och mitt personnummer är 850612-1234.",
            options=redaction_v1_pb2.Options(
                entities=[redaction_v1_pb2.EntityType.name, redaction_v1_pb2.EntityType.personalNumber],
                rules=redaction_v1_pb2.Rules(
                    name=redaction_v1_pb2.NameRules(method=redaction_v1_pb2.Method.replaceWithInitials),
                    personalNumber=redaction_v1_pb2.PersonalNumberRules(method=redaction_v1_pb2.Method.remove)
                )
            )
        )
        md = [('authorization', API_KEY)]
        resp = stub.RedactText(req, metadata=md)
        print(resp.result.redactedText)

if __name__ == "__main__":
    run()

Regelkonfiguration (Options)

Meddelandet Options är valfritt. Om du utelämnar det används standardläget: namn, adress och personnummer maskeras.

Strukturen består av två delar:

  • entities – en lista med de EntityType som API:t ska leta efter och behandla.
  • rules – ett objekt där du kan specificera detaljerade regler för varje entitetstyp.

Övergripande struktur: Options

FältBeskrivning
entities
repeated EntityType
Vilka entiteter som ska avidentifieras. Värden: name, address, email, phoneNumber, personalNumber.
rules
Rules
Ett objekt som innehåller en default-regel och specifika regler för varje entitetstyp (t.ex. name, address). Specifika regler ärver från och skriver över default-regeln.

Gemensamma regelfält (gäller alla entiteter)

FältBeskrivning
method
Method
Hur värdet ska hanteras: mask, replaceWithInitials (endast för name), replaceWith, remove.
replacementText
string
Krävs om method är replaceWith.
maskingCharacter
string
Tecken som används vid textmaskering när method är mask. Standard är "█".
fillColor / textColor
string
Hex-färger (#RRGGBB eller #RRGGBBAA) för visuell redigering i PDF/DOCX.
findValues / ignoreValues
repeated string
Listor med strängar för att tvinga fram eller ignorera specifika matchningar.

Entitetsspecifika regelfält

FältGäller förBeskrivning
minNameParts
int32
nameMinsta antal ord som ska betraktas som ett fullständigt namn (t.ex. 2 för "Anna Andersson").
redactPersonNamedCompanies
bool
nameOm true, avidentifieras även företagsnamn som liknar personnamn (t.ex. "Eriksson AB").
mode
string
addressTyp av adress att matcha: "fullAddress", "anyAddress", "streetAddress".
minConfidence
double
name, addressTröskelvärde för konfidens (0.0–1.0) vid matchning.

Idempotens

För att göra säkra retries utan att orsaka dubbeldebitering kan du skicka med metadata-headern idempotency-key: <unik-nyckel>. Detta är valfritt men rekommenderat för robusta integrationer.

Om ett anrop med en specifik nyckel lyckas, kommer efterföljande anrop med samma nyckel och identisk request-payload inom 15 minuter att returnera det cachade svaret istället för att utföra operationen på nytt.

Svaret innehåller två trailers (metadata som skickas efter responsen) för att bekräfta status:

  • idempotency-key: Ekar nyckeln som användes. Om du inte skickade en, innehåller den en server-genererad nyckel.
  • idempotency-status: Antingen created (första lyckade anropet) eller replayed (ett cachat svar returnerades).

Felhantering

API:t använder standardiserade gRPC-statuskoder för att signalera resultat. Vid valideringsfel (INVALID_ARGUMENT) skickas en mer detaljerad felbeskrivning enligt Google RPC Error Model i trailern grpc-status-details-bin.

StatuskodBetydelse
OKAnropet lyckades.
INVALID_ARGUMENTOgiltig indata, t.ex. saknat fält eller felaktiga värden i Options. Detaljer finns i trailers.
UNAUTHENTICATEDAPI-nyckel saknas eller är ogiltig.
FAILED_PRECONDITIONEn förutsättning är inte uppfylld, t.ex. filtypen som skickades stöds inte.
RESOURCE_EXHAUSTEDDin dagliga sidkvot har överskridits.
ALREADY_EXISTSIdempotenskonflikt. Samma idempotency-key har använts med en annan request-payload.
INTERNALEtt oväntat serverfel inträffade.
Avidentifiera Avidentifiera
Automatisera borttagning av känsliga uppgifter. © 2025 Avidentifiera |
Avidentifiera Avidentifiera Cookies
Vi använder cookies för att säkerställa webbplatsens funktionalitet. Du kan när som helst justera inställningar för analys och marknadsföring (avstängt som standard). Läs vår Cookiepolicy.