diff --git a/supporting-blog-content/lexical-and-semantic-search-with-elasticsearch/ecommerce_dense_sparse_project.ipynb b/supporting-blog-content/lexical-and-semantic-search-with-elasticsearch/ecommerce_dense_sparse_project.ipynb
index b8d8a7b5..e7fd774b 100644
--- a/supporting-blog-content/lexical-and-semantic-search-with-elasticsearch/ecommerce_dense_sparse_project.ipynb
+++ b/supporting-blog-content/lexical-and-semantic-search-with-elasticsearch/ecommerce_dense_sparse_project.ipynb
@@ -1106,8 +1106,8 @@
"metadata": {},
"outputs": [],
"source": [
- "\"\"\" Convert search_results from es|ql to a dict with _source\n",
- " and subproperties of score, description, category, and product \"\"\"\n",
+ "\"\"\"Convert search_results from es|ql to a dict with _source\n",
+ "and subproperties of score, description, category, and product\"\"\"\n",
"\n",
"\n",
"def normalize_results(search_results):\n",
diff --git a/supporting-blog-content/your-first-elastic-agent/Your_First_Elastic_Agent.ipynb b/supporting-blog-content/your-first-elastic-agent/Your_First_Elastic_Agent.ipynb
index 5162b81b..e61d7c62 100644
--- a/supporting-blog-content/your-first-elastic-agent/Your_First_Elastic_Agent.ipynb
+++ b/supporting-blog-content/your-first-elastic-agent/Your_First_Elastic_Agent.ipynb
@@ -69,6 +69,8 @@
"output_type": "stream",
"name": "stdout",
"text": [
+ "Enter your Elasticsearch Endpoint URL: https://your-first-elastic-agent-a4dc2b.es.us-central1.gcp.elastic.cloud:443\n",
+ "Enter your Elasticsearch API Key: bmU3SGRKa0JJdGhRdS1VdGJ5STg6a0ViYkZKcXA5ekx6LWNEZkR2TGxvZw==\n",
"Using connection details:\n",
"Elasticsearch URL: https://your-first-elastic-agent-a4dc2b.es.us-central1.gcp.elastic.cloud:443\n",
"Kibana URL: https://your-first-elastic-agent-a4dc2b.kb.us-central1.gcp.elastic.cloud:443\n",
diff --git a/supporting-video-content/create_an_elastic_serverless_project_programmatically/Create_an_Elastic_Serverless_Search_Project_Programmatically.ipynb b/supporting-video-content/create_an_elastic_serverless_project_programmatically/Create_an_Elastic_Serverless_Search_Project_Programmatically.ipynb
new file mode 100644
index 00000000..b2a2276e
--- /dev/null
+++ b/supporting-video-content/create_an_elastic_serverless_project_programmatically/Create_an_Elastic_Serverless_Search_Project_Programmatically.ipynb
@@ -0,0 +1,343 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "provenance": []
+ },
+ "kernelspec": {
+ "name": "python3",
+ "display_name": "Python 3"
+ },
+ "language_info": {
+ "name": "python"
+ }
+ },
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "source": [
+ "# Create an Elastic Serverless Search Project Programmatically\n",
+ "\n",
+ "\n",
+ "## This notebook will show you how to:\n",
+ " - Create an Elastics Serverless Project\n",
+ "\n",
+ "[Serverless API Docs](https://www.elastic.co/docs/api/doc/elastic-cloud-serverless/operation/operation-createelasticsearchproject#operation-createelasticsearchproject-body-application-json-optimized_for)\n",
+ "\n",
+ "This tutorial assumes you have an Elastic Cloud account.
\n",
+ "If not head over to [cloud.elastic.co/trial](https://cloud.elastic.co/trial)"
+ ],
+ "metadata": {
+ "id": "_ebYbHHh_0hI"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "# Notebook Setup\n",
+ "- Install elasticsearch python library\n",
+ "- import required libraries"
+ ],
+ "metadata": {
+ "id": "JBHESuD7PJ54"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "!pip install -qq elasticsearch"
+ ],
+ "metadata": {
+ "id": "_DmXlQWsGNeM",
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "outputId": "6c04a6f7-a4e7-4e96-faaf-04d9bf2e9af7"
+ },
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "\u001b[?25l \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/960.5 kB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r\u001b[2K \u001b[91m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[91m╸\u001b[0m \u001b[32m952.3/960.5 kB\u001b[0m \u001b[31m28.8 MB/s\u001b[0m eta \u001b[36m0:00:01\u001b[0m\r\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m960.5/960.5 kB\u001b[0m \u001b[31m17.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+ "\u001b[?25h\u001b[?25l \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/65.3 kB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m65.3/65.3 kB\u001b[0m \u001b[31m4.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+ "\u001b[?25h"
+ ]
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "import requests\n",
+ "import getpass\n",
+ "from pprint import pprint\n",
+ "from elasticsearch import Elasticsearch\n",
+ "from elasticsearch.exceptions import ConnectionTimeout\n",
+ "from IPython.display import clear_output\n",
+ "from time import sleep"
+ ],
+ "metadata": {
+ "id": "cuomUVE-zYjB"
+ },
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "# Setup Your Cloud API Key\n",
+ "\n",
+ "1. Generate your secret API key at https://cloud.elastic.co/account/keys\n",
+ "2. Run the next cell to store your API Key"
+ ],
+ "metadata": {
+ "id": "yWSg_D91x9mF"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "api_key = getpass.getpass(\"Enter your API key: \")\n",
+ "\n",
+ "print(\"API key successfully entered!\")"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "bidHlfsy2OPf",
+ "outputId": "33eceaab-1963-4c36-992a-ed96cd98904a"
+ },
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "Enter your API key: ··········\n",
+ "API key successfully entered!\n"
+ ]
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "## Create Elasticsearch project\n"
+ ],
+ "metadata": {
+ "id": "mt4_kL0b0E75"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "Configure:\n",
+ "- name of project - `name`\n",
+ "- cloud region - `region_id`\n",
+ "- headers\n",
+ "\n",
+ "Then create the project!"
+ ],
+ "metadata": {
+ "id": "ZcQ2AgeNQHOA"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "url = \"https://api.elastic-cloud.com/api/v1/serverless/projects/elasticsearch\"\n",
+ "\n",
+ "project_data = {\"name\": \"Serverless Search Project\", \"region_id\": \"aws-us-east-1\"}\n",
+ "\n",
+ "auth_header = f\"ApiKey {api_key}\"\n",
+ "headers = {\"Content-Type\": \"application/json\", \"Authorization\": auth_header}\n",
+ "\n",
+ "es_project = requests.post(url, json=project_data, headers=headers)"
+ ],
+ "metadata": {
+ "id": "lVkyA7KUyDEO"
+ },
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "Serverless projects generally start pretty quickly
We'll loop and wait for the project to be configured and ready to use"
+ ],
+ "metadata": {
+ "id": "3oFstW-wQVWl"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "if 200 <= es_project.status_code < 300:\n",
+ " es_project_keys = es_project.json()\n",
+ " prg_name = es_project_keys[\"name\"]\n",
+ " print(f\"Project {prg_name} creation started\")\n",
+ "\n",
+ " # wait for the project to be initialized and ready\n",
+ " project_id = es_project.json()[\"id\"]\n",
+ " print(\"Checking if project is created and ready\")\n",
+ " loop = 1\n",
+ " while True:\n",
+ " es_project_check = requests.get(url + f\"/{project_id}/status\", headers=headers)\n",
+ " if es_project_check.json()[\"phase\"] == \"initialized\":\n",
+ " break\n",
+ " else:\n",
+ " clear_output(wait=True)\n",
+ " print(\n",
+ " f\"Waiting for project to be ready. Current status:{es_project_check.json()['phase']} - Loop {loop} Sleeping 10 seconds\"\n",
+ " )\n",
+ " sleep(10)\n",
+ " loop += 1\n",
+ "\n",
+ " print(\"Project is ready\")\n",
+ "\n",
+ "else:\n",
+ " print(es_project.text)"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "jlOjE8l5QU91",
+ "outputId": "b7ecd36e-62df-4d29-e75f-121aa37e2d76"
+ },
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "Waiting for project to be ready. Current status:initializing - Loop 16 Sleeping 10 seconds\n",
+ "Project is ready\n"
+ ]
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "# Retrieve Serverless Project Connection Information"
+ ],
+ "metadata": {
+ "id": "RogmJvonQnRu"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "## Create elasticsearch client\n",
+ "\n",
+ "We set the connection information from the `es_project` response above."
+ ],
+ "metadata": {
+ "id": "Uh0JpsnONMhv"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "es = Elasticsearch(\n",
+ " es_project_keys[\"endpoints\"][\"elasticsearch\"],\n",
+ " basic_auth=(\n",
+ " es_project_keys[\"credentials\"][\"username\"],\n",
+ " es_project_keys[\"credentials\"][\"password\"],\n",
+ " ),\n",
+ ")"
+ ],
+ "metadata": {
+ "id": "KG01YrIwMdHz"
+ },
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "## Project API Key\n",
+ "Create a [Project level API key](https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-api-key.html)"
+ ],
+ "metadata": {
+ "id": "Xhu2U-YszbDe"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "project_key_response = es.security.create_api_key(\n",
+ " name=\"full_access_key\",\n",
+ " metadata={\"description\": \"API key for full access\"},\n",
+ " expiration=\"14d\",\n",
+ ")\n",
+ "\n",
+ "project_api_key = project_key_response[\"encoded\"]\n",
+ "print(f\"{project_key_response['name']} has been created\")"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "Puj1UWIKVtSv",
+ "outputId": "b195543a-2206-4a20-8d10-b80030d276de"
+ },
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "full_access_key has been created\n"
+ ]
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "# Summary"
+ ],
+ "metadata": {
+ "id": "EnKDbhz6RIYx"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "print(\"\\n--- Project Summary ---\")\n",
+ "print(f\"Project Name: {es_project_keys['name']}\")\n",
+ "print(f\"Elasticsearch Endpoint: {es_project_keys['endpoints']['elasticsearch']}\")\n",
+ "if \"kibana\" in es_project_keys[\"endpoints\"]:\n",
+ " print(f\"Kibana Endpoint: {es_project_keys['endpoints']['kibana']}\")\n",
+ "else:\n",
+ " print(\n",
+ " \"Kibana Endpoint: Not available (Kibana may not be part of the serverless project)\"\n",
+ " )\n",
+ "\n",
+ "\n",
+ "print(\"\\n--- API Key ---\")\n",
+ "print(f\"API key stored in variable: project_api_key\")\n",
+ "\n",
+ "show_api_key = input(\n",
+ " \"Do you want to print the API key in clear text? (yes/no): \"\n",
+ ").lower()\n",
+ "\n",
+ "if show_api_key == \"yes\":\n",
+ " print(f\"Project API Key: {project_api_key}\")\n",
+ "else:\n",
+ " print(\"API key not printed in clear text as requested. Stored in `project_api_key`\")"
+ ],
+ "metadata": {
+ "id": "ACDRmumLRGd_"
+ },
+ "execution_count": null,
+ "outputs": []
+ }
+ ]
+}