> ## Documentation Index
> Fetch the complete documentation index at: https://docs.runmorph.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Introduction

> Create your first connection

<Accordion title="Try a live demo ✨">
  <Check>
    **Live Demo** <br />
    Select a connector below to experience our seamless authentication flow and see
    how easy it is to connect third-party services.
  </Check>

  <iframe src="https://atoms-playground.vercel.app?theme=light" width="100%" height="370px" className="block dark:hidden" />

  <iframe src="https://atoms-playground.vercel.app?theme=dark" width="100%" height="370px" className="hidden dark:block" />
</Accordion>

## How it works

<Steps>
  <Step title="Create Connection">
    Create a connection using [POST
    /connections](https://runmoprh.dev/api-reference/connection/create-a-connection)
    by providing a `connectorId` and an `ownerId`. The `ownerId` is a unique
    identifier defined by you, typically representing a customer or user ID.

    <CodeGroup>
      ```typescript TypeScript theme={null}
      import { Morph } from "@runmorph/cloud";

      // initialize the Morph client with your API credentials
      const morph = Morph({
        publicKey: "pk_demo_xxxxxxxxxxxxxxx",
        secretKey: "sk_demo_xxxxxxxxxxxxxxx",
      });

      // initialize the connection
      const connection = morph.connections({
        connectorId: "hubspot",
        ownerId: "demo",
      });

      // create the connection with the required operations
      await connection.create({
        operations: [ "genericContact::list" ],
      });
      ```

      ```python Python theme={null}
      morph = Morph(api_key="pk_demo_xxxxxxxxxxxxxxx", api_secret="sk_demo_xxxxxxxxxxxxxxx")

      # create a new connection
      connection = morph.connections(connector_id="hubspot", owner_id="demo")
      connection.create(operations=["genericContact::create","genericUser::list"])
      ```

      ```ruby Ruby theme={null}
      morph = Morph.new(api_key: "pk_demo_xxxxxxxxxxxxxxx", api_secret: "sk_demo_xxxxxxxxxxxxxxx")

      # create a new connection
      connection = morph.connections(connector_id: "hubspot", owner_id: "demo")
      connection.create(operations: ["genericContact::create","genericUser::list"])
      ```

      ```php PHP theme={null}
      $morph = new Morph([
        'api_key' => 'pk_demo_xxxxxxxxxxxxxxx',
        'api_secret' => 'sk_demo_xxxxxxxxxxxxxxx'
      ]);

      // create a new connection
      $connection = $morph->connections([
        'connector_id' => 'hubspot',
        'owner_id' => 'demo'
      ]);
      $connection->create(['operations' => ['genericContact::create','genericUser::list']]);
      ```

      ```go Go theme={null}
      morph := morph.New(&morph.Config{
          publicKey:    "pk_demo_xxxxxxxxxxxxxxx",
          secretKey: "sk_demo_xxxxxxxxxxxxxxx",
      })

      // create a new connection
      connection := morph.Connections(&morph.ConnectionConfig{
          ConnectorId: "hubspot",
          OwnerId:    "demo",
      })
      connection.Create(&morph.CreateConfig{
          Operations: []string{"genericContact::create", "genericUser::list"},
      })
      ```
    </CodeGroup>
  </Step>

  <Step title="Authorize Connection">
    Authorize the connection using [POST
    /authorization](https://runmoprh.dev/api-reference/connection/authorize-a-connection)
    to obtain the `authorizationUrl` required to initiate the OAuth flow.

    <CodeGroup>
      ```typescript TypeScript theme={null}
      // auhtorize the connection
      const { auhtorizationUrl } = await connection.authorize();

      // redirect the user to the auhtorizationUrl

      ```

      ```python Python theme={null}
      # authorize the connection
      auth_result = connection.authorize()
      authorization_url = auth_result["authorization_url"]

      # redirect the user to the authorization_url
      ```

      ```ruby Ruby theme={null}
      # authorize the connection
      auth_result = connection.authorize
      authorization_url = auth_result[:authorization_url]

      # redirect the user to the authorization_url
      ```

      ```php PHP theme={null}
      // auhtorize the connection
      $authResult = $connection->authorize();
      $authorizationUrl = $authResult['authorization_url'];

      // redirect the user to the auhtorizationUrl
      ```

      ```go Go theme={null}
      // authorize the connection
      authResult, _ := connection.Authorize()
      authorizationUrl := authResult.AuthorizationUrl

      // redirect the user to the authorization URL
      ```
    </CodeGroup>
  </Step>

  <Step title="CRUD Resources">
    Once connected, you can perform CRUD operations on any unified resources
    available in the [/resources](api-reference/models/intro) endpoint. You can
    also make authenticated HTTP requests to the connector's API using
    [/proxy](https://runmoprh.dev/api-reference/proxy).

    <CodeGroup>
      ```typescript TypeScript theme={null}
      // CRUD Resources
      // Access a specific resource model
      const contacts = connection.resources("genericContact");

      // Create a resource
      const { data, error } = await contacts.create({
        firstName: "John",
        lastName: "Doe",
        email: "john.doe@corp.co"
      });

      // Retrieve a specific resource
      const { data, error } = await contacts.retrieve("contact-123", {
        fields: ["email", "firstName"],
      });

      // List resources
      const { data, next, error } = await contacts.list({
        limit: 10,
        cursor: "next-page-cursor",
      });

      // Update a resource
      const { data, error } = await contacts.update("contact-123", {
        firstName: "Jane",
      });

      // Proxy
      // Check the connector used for a given connection
      const hubspotConnection = connection.isConnector("hubspot");
      if (!hubspotConnection) return;

      // Now you know for sure it's a HubSpot connection – you can call HubSpot API endpoint directly
      const { data, error } = await hubspotConnection.proxy({
        path: "/v3/objects/contacts",
        method: "GET",
        query: { limit: 10 },
      });

      ```

      ```python Python theme={null}
      # CRUD Resources
      # Access a specific resource model
      contacts = connection.resources("genericContact")

      # Create a resource
      data, error = contacts.create({
        "firstName": "John",
        "lastName": "Doe",
        "email": "john.doe@corp.co"
      })

      # Retrieve a specific resource
      data, error = contacts.retrieve("contact-123", {
          "fields": ["email", "firstName"]
      })

      # List resources
      data, next_cursor, error = contacts.list({
          "limit": 10,
          "cursor": "next-page-cursor"
      })

      # Update a resource
      data, error = contacts.update("contact-123", {
          "firstName": "Jane"
      })

      # Proxy
      # Check the connector used for a given connection
      hubspot_connection = connection.is_connector("hubspot")
      if not hubspot_connection:
          exit()

      # Now you know for sure it's a HubSpot connection – you can call HubSpot API endpoint directly
      data, error = hubspot_connection.proxy({
          "path": "/v3/objects/contacts",
          "method": "GET",
          "query": { "limit": 10 }
      })
      ```

      ```ruby Ruby theme={null}
      # CRUD Resources
      # Access a specific resource model
      contacts = connection.resources("genericContact")

      # Create a resource
      data, error = contacts.create({
        firstName: "John",
        lastName: "Doe",
        email: "john.doe@corp.co"
      })

      # Retrieve a specific resource
      data, error = contacts.retrieve("contact-123", {
        fields: ["email", "firstName"]
      })

      # List resources
      data, next_cursor, error = contacts.list({
        limit: 10,
        cursor: "next-page-cursor"
      })

      # Update a resource
      data, error = contacts.update("contact-123", {
        firstName: "Jane"
      })

      # Proxy
      # Check the connector used for a given connection
      hubspot_connection = connection.is_connector("hubspot")
      return unless hubspot_connection

      # Now you know for sure it's a HubSpot connection – you can call HubSpot API endpoint directly
      data, error = hubspot_connection.proxy({
        path: "/v3/objects/contacts",
        method: "GET",
        query: { limit: 10 }
      })
      ```

      ```php PHP theme={null}
      // CRUD Resources
      // Access a specific resource model
      $contacts = $connection->resources("genericContact");

      // Create a resource
      [$data, $error] = $contacts->create([
          "firstName" => "John",
          "lastName" => "Doe",
          "email" => "john.doe@corp.co"
      ]);

      // Retrieve a specific resource
      [$data, $error] = $contacts->retrieve("contact-123", [
          "fields" => ["email", "firstName"]
      ]);

      // List resources
      [$data, $next, $error] = $contacts->list([
          "limit" => 10,
          "cursor" => "next-page-cursor"
      ]);

      // Update a resource
      [$data, $error] = $contacts->update("contact-123", [
          "firstName" => "Jane"
      ]);

      // Proxy
      // Check the connector used for a given connection
      $hubspotConnection = $connection->isConnector("hubspot");
      if (!$hubspotConnection) {
          return;
      }

      // Now you know for sure it's a HubSpot connection – you can call HubSpot API endpoint directly
      [$data, $error] = $hubspotConnection->proxy([
          "path" => "/v3/objects/contacts",
          "method" => "GET",
          "query" => ["limit" => 10]
      ]);
      ```

      ```go Go theme={null}
      	// CRUD Resources
      	// Access a specific resource model
      	contacts := connection.Resources("genericContact")

      	// Create a resource
      	data, err := contacts.Create(map[string]interface{}{
      		"firstName": "John",
      		"lastName":  "Doe",
      		"email":     "john.doe@corp.co",
      	})


      	// Retrieve a specific resource
      	data, err = contacts.Retrieve("contact-123", map[string]interface{}{
      		"fields": []string{"email", "firstName"},
      	})


      	// List resources
      	data, nextCursor, err := contacts.List(map[string]interface{}{
      		"limit":  10,
      		"cursor": "next-page-cursor",
      	})


      	// Update a resource
      	data, err = contacts.Update("contact-123", map[string]interface{}{
      		"firstName": "Jane",
      	})

      	// Proxy
      	// Check the connector used for a given connection
      	hubspotConnection := connection.IsConnector("hubspot")
      	if !hubspotConnection {
      		fmt.Println("Not a HubSpot connection")
      		return
      	}

      	// Now you know for sure it's a HubSpot connection – you can call HubSpot API endpoint directly
      	data, err = hubspotConnection.Proxy(map[string]interface{}{
      		"path":   "/v3/objects/contacts",
      		"method": "GET",
      		"query":  map[string]interface{}{"limit": 10},
      	})
      ```
    </CodeGroup>
  </Step>
</Steps>

Let's get started:

<CardGroup cols={2}>
  <Card title="Create Connection" icon="key-skeleton" iconType="duotone" href="./connection/create-a-connection">
    Create your first connection with your preferred connector.
  </Card>
</CardGroup>
