diff --git a/ocm/README.md b/ocm/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..06775a0b0c0c4c37e1416fa2f7b20381592b6625
--- /dev/null
+++ b/ocm/README.md
@@ -0,0 +1,26 @@
+# Go client for the OCM service
+
+This go package contains client for communication with the OCM service.
+
+### Installation
+
+```shell
+go get code.vereign.com/gaiax/tsa/golib/ocm@latest
+```
+
+###Usage
+
+In order to use this package you must import it in your application and
+instantiate the client given the OCM service address like this:
+
+```
+import "code.vereign.com/gaiax/tsa/golib/ocm"
+
+func main() {
+    client := ocm.New(ocmAddress)
+}
+```
+
+###License
+
+See [LICENSE](../LICENSE) for the full license.
\ No newline at end of file
diff --git a/ocm/client.go b/ocm/client.go
new file mode 100644
index 0000000000000000000000000000000000000000..abe0bacb2113bf4523507f009b08b7095de039c2
--- /dev/null
+++ b/ocm/client.go
@@ -0,0 +1,66 @@
+package ocm
+
+import (
+	"bytes"
+	"context"
+	"encoding/json"
+	"fmt"
+	"io"
+	"net/http"
+)
+
+// Client is the OCM service client
+type Client struct {
+	addr       string
+	httpClient *http.Client
+}
+
+// New initializes an OCM service client given the OCM service address
+func New(addr string, opts ...Option) *Client {
+	c := &Client{
+		addr:       addr,
+		httpClient: http.DefaultClient,
+	}
+
+	for _, opt := range opts {
+		opt(c)
+	}
+
+	return c
+}
+
+// GetLoginProofInvitation calls the "invitation" endpoint on
+// the "out-of-band" protocol in the OCM service.
+func (c *Client) GetLoginProofInvitation(ctx context.Context, r *LoginProofInvitationRequest) (*LoginProofInvitationResponse, error) {
+	b, err := json.Marshal(r)
+	if err != nil {
+		return nil, err
+	}
+
+	req, err := http.NewRequestWithContext(ctx, "POST", c.addr+"/out-of-band/1.0/invitation", bytes.NewReader(b))
+	if err != nil {
+		return nil, err
+	}
+
+	resp, err := c.httpClient.Do(req)
+	if err != nil {
+		return nil, err
+	}
+	defer resp.Body.Close() // nolint:errcheck
+
+	if resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf("unexpected response code: %d", resp.StatusCode)
+	}
+
+	bytes, err := io.ReadAll(resp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	var response *LoginProofInvitationResponse
+	if err := json.Unmarshal(bytes, &response); err != nil {
+		return nil, err
+	}
+
+	return response, nil
+}
diff --git a/ocm/client_test.go b/ocm/client_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..4a58c1ffd46b0a6a3f3698ddd1094c7caf2db6b2
--- /dev/null
+++ b/ocm/client_test.go
@@ -0,0 +1,75 @@
+package ocm_test
+
+import (
+	"context"
+	"encoding/json"
+	"io"
+	"net/http"
+	"net/http/httptest"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+
+	"code.vereign.com/gaiax/tsa/golib/ocm"
+)
+
+func Test_GetLoginProofInvitationSuccess(t *testing.T) {
+	expected := &ocm.LoginProofInvitationResponse{
+		StatusCode: 200,
+		Message:    "success",
+	}
+
+	ocmServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		expectedRequestBody := `{"comment":"test","attributes":null,"schemaId":"schema:1.0","participantId":"12345"}`
+		bodyBytes, err := io.ReadAll(r.Body)
+		assert.NoError(t, err)
+
+		bodyString := string(bodyBytes)
+		assert.Equal(t, expectedRequestBody, bodyString)
+
+		w.WriteHeader(http.StatusOK)
+		_ = json.NewEncoder(w).Encode(expected)
+	}))
+
+	req := &ocm.LoginProofInvitationRequest{
+		Comment:       "test",
+		Attributes:    nil,
+		SchemaID:      "schema:1.0",
+		ParticipantID: "12345",
+	}
+
+	client := ocm.New(ocmServer.URL)
+	res, err := client.GetLoginProofInvitation(context.Background(), req)
+
+	assert.NoError(t, err)
+	assert.Equal(t, expected.StatusCode, res.StatusCode)
+	assert.Equal(t, expected.Message, res.Message)
+	assert.Equal(t, expected.Data, res.Data)
+}
+
+func Test_GetLoginProofInvitationErr(t *testing.T) {
+	ocmServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		expectedRequestBody := `{"comment":"test","attributes":null,"schemaId":"schema:1.0","participantId":"12345"}`
+		bodyBytes, err := io.ReadAll(r.Body)
+		assert.NoError(t, err)
+
+		bodyString := string(bodyBytes)
+		assert.Equal(t, expectedRequestBody, bodyString)
+
+		w.WriteHeader(http.StatusInternalServerError)
+	}))
+
+	req := &ocm.LoginProofInvitationRequest{
+		Comment:       "test",
+		Attributes:    nil,
+		SchemaID:      "schema:1.0",
+		ParticipantID: "12345",
+	}
+
+	client := ocm.New(ocmServer.URL)
+	res, err := client.GetLoginProofInvitation(context.Background(), req)
+
+	assert.Nil(t, res)
+	assert.Error(t, err)
+	assert.Contains(t, err.Error(), "unexpected response code")
+}
diff --git a/ocm/option.go b/ocm/option.go
new file mode 100644
index 0000000000000000000000000000000000000000..3b7ba4cfbd986bdb96272ae92911e3f08b69781b
--- /dev/null
+++ b/ocm/option.go
@@ -0,0 +1,11 @@
+package ocm
+
+import "net/http"
+
+type Option func(*Client)
+
+func WithHTTPClient(client *http.Client) Option {
+	return func(c *Client) {
+		c.httpClient = client
+	}
+}
diff --git a/ocm/types.go b/ocm/types.go
new file mode 100644
index 0000000000000000000000000000000000000000..fa12f15a01869872b1328283928592a65aa75a2b
--- /dev/null
+++ b/ocm/types.go
@@ -0,0 +1,25 @@
+package ocm
+
+type LoginProofInvitationRequest struct {
+	Comment       string      `json:"comment"`
+	Attributes    []Attribute `json:"attributes"`
+	SchemaID      string      `json:"schemaId"`
+	ParticipantID string      `json:"participantId"`
+}
+
+type Attribute struct {
+	AttributeName string `json:"attributeName"`
+	Value         string `json:"value"`
+	Condition     string `json:"condition"`
+}
+
+type LoginProofInvitationResponse struct {
+	StatusCode int                              `json:"statusCode"`
+	Message    string                           `json:"message"`
+	Data       LoginProofInvitationResponseData `json:"data"`
+}
+
+type LoginProofInvitationResponseData struct {
+	PresentationID      string `json:"presentationId"`
+	PresentationMessage string `json:"presentationMessage"`
+}