diff --git a/scheduler/README.md b/scheduler/README.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/scheduler/app.yaml b/scheduler/app.yaml
new file mode 100644
index 00000000000..8afa34736da
--- /dev/null
+++ b/scheduler/app.yaml
@@ -0,0 +1,18 @@
+# Copyright 2019 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the 'License');
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an 'AS IS' BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# [START cloud_scheduler_python_yaml]
+runtime: python37
+service: my-service
+# [END cloud_scheduler_python_yaml]
diff --git a/scheduler/create_job.py b/scheduler/create_job.py
new file mode 100644
index 00000000000..f5025ca1a34
--- /dev/null
+++ b/scheduler/create_job.py
@@ -0,0 +1,77 @@
+# Copyright 2019 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the 'License');
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an 'AS IS' BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+def create_scheduler_job(project_id, location_id, service_id):
+    """Create a job with an App Engine target via the Cloud Scheduler API"""
+    # [START cloud_scheduler_create_job]
+    from google.cloud import scheduler
+
+    # Create a client.
+    client = scheduler.CloudSchedulerClient()
+
+    # TODO(developer): Uncomment and set the following variables
+    # project_id = 'PROJECT_ID'
+    # location_id = 'LOCATION_ID'
+    # service_id = 'my-service'
+
+    # Construct the fully qualified location path.
+    parent = client.location_path(project_id, location_id)
+
+    # Construct the request body.
+    job = {
+        'app_engine_http_target': {
+            'app_engine_routing': {
+                'service': service_id
+            },
+            'relative_uri': '/log_payload',
+            'http_method': 'POST',
+            'body': 'Hello World'.encode()
+        },
+        'schedule': '* * * * *',
+        'time_zone': 'America/Los_Angeles'
+    }
+
+    # Use the client to send the job creation request.
+    response = client.create_job(parent, job)
+
+    print('Created job: {}'.format(response.name))
+    # [END cloud_scheduler_create_job]
+    return response
+
+
+def delete_scheduler_job(project_id, location_id, job_id):
+    """Delete a job via the Cloud Scheduler API"""
+    # [START cloud_scheduler_delete_job]
+    from google.cloud import scheduler
+    from google.api_core.exceptions import GoogleAPICallError
+
+    # Create a client.
+    client = scheduler.CloudSchedulerClient()
+
+    # TODO(developer): Uncomment and set the following variables
+    # project_id = 'PROJECT_ID'
+    # location_id = 'LOCATION_ID'
+    # job_id = 'JOB_ID'
+
+    # Construct the fully qualified job path.
+    job = client.job_path(project_id, location_id, job_id)
+
+    # Use the client to send the job deletion request.
+    try:
+        client.delete_job(job)
+        print("Job deleted.")
+    except GoogleAPICallError as e:
+        print("Error: %s" % e)
+    # [END cloud_scheduler_delete_job]
diff --git a/scheduler/create_job_test.py b/scheduler/create_job_test.py
new file mode 100644
index 00000000000..ab03c1b7629
--- /dev/null
+++ b/scheduler/create_job_test.py
@@ -0,0 +1,33 @@
+# Copyright 2019 Google Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+
+import create_job
+
+TEST_PROJECT_ID = os.getenv('GCLOUD_PROJECT')
+TEST_LOCATION = os.getenv('LOCATION_ID', 'us-central1')
+
+
+def test_create_job(capsys):
+    create_result = create_job.create_scheduler_job(
+        TEST_PROJECT_ID, TEST_LOCATION, 'my-service')
+    out, _ = capsys.readouterr()
+    assert 'Created job:' in out
+
+    job_name = create_result.name.split('/')[-1]
+    create_job.delete_scheduler_job(TEST_PROJECT_ID, TEST_LOCATION, job_name)
+
+    out, _ = capsys.readouterr()
+    assert 'Job deleted.' in out
diff --git a/scheduler/main.py b/scheduler/main.py
new file mode 100644
index 00000000000..9d4d97537d2
--- /dev/null
+++ b/scheduler/main.py
@@ -0,0 +1,42 @@
+# Copyright 2019 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""App Engine app to serve as an endpoint for Cloud Scheduler samples."""
+
+# [START cloud_scheduler_app]
+from flask import Flask, request
+
+app = Flask(__name__)
+
+
+# Define relative URI for job endpoint
+@app.route('/log_payload', methods=['POST'])
+def example_task_handler():
+    """Log the job payload."""
+    payload = request.get_data(as_text=True) or '(empty payload)'
+    print('Received job with payload: {}'.format(payload))
+    return 'Printed job payload: {}'.format(payload)
+# [END cloud_scheduler_app]
+
+
+@app.route('/')
+def hello():
+    """Basic index to verify app is serving."""
+    return 'Hello World!'
+
+
+if __name__ == '__main__':
+    # This is used when running locally. Gunicorn is used to run the
+    # application on Google App Engine. See entrypoint in app.yaml.
+    app.run(host='127.0.0.1', port=8080, debug=True)
diff --git a/scheduler/main_test.py b/scheduler/main_test.py
new file mode 100644
index 00000000000..3d6745a5605
--- /dev/null
+++ b/scheduler/main_test.py
@@ -0,0 +1,45 @@
+# Copyright 2019 Google Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import pytest
+
+
+@pytest.fixture
+def app():
+    import main
+    main.app.testing = True
+    return main.app.test_client()
+
+
+def test_index(app):
+    r = app.get('/')
+    assert r.status_code == 200
+
+
+def test_log_payload(capsys, app):
+    payload = 'test_payload'
+
+    r = app.post('/log_payload', data=payload)
+    assert r.status_code == 200
+
+    out, _ = capsys.readouterr()
+    assert payload in out
+
+
+def test_empty_payload(capsys, app):
+    r = app.post('/log_payload')
+    assert r.status_code == 200
+
+    out, _ = capsys.readouterr()
+    assert 'empty payload' in out
diff --git a/scheduler/requirements.txt b/scheduler/requirements.txt
new file mode 100644
index 00000000000..6fc789799aa
--- /dev/null
+++ b/scheduler/requirements.txt
@@ -0,0 +1,3 @@
+Flask==1.0.2
+gunicorn==19.9.0
+google-cloud-scheduler==0.1.0